<% def date_picker_template(start_date = Date.current, end_date = Date.current)
start_picker = text_field_tag "event[date_ranges_attributes][][start_date]", (I18n.l start_date),
class: 'form-control', :"data-enable-datepicker" => 'true'
diff --git a/app/views/events/index.html.erb b/app/views/events/index.html.erb
index e7d71f97..9fc69024 100644
--- a/app/views/events/index.html.erb
+++ b/app/views/events/index.html.erb
@@ -1,6 +1,6 @@
<%- model_class = Event -%>
@@ -22,13 +22,17 @@
<%= event.end_date %> |
<%= event.draft %> |
- <%= link_to t('.edit', :default => t('helpers.links.edit')),
+ <% if can? :edit, event %>
+ <%= link_to t('.edit', :default => t('helpers.links.edit')),
edit_event_path(event), :class => 'btn btn-default btn-xs' %>
- <%= link_to t('.destroy', :default => t('helpers.links.destroy')),
+ <% end %>
+ <% if can? :destroy, event %>
+ <%= link_to t('.destroy', :default => t('helpers.links.destroy')),
event_path(event),
:method => :delete,
:data => { :confirm => t('events.confirmation_prompts.confirm_delete', :default => t("helpers.links.confirm", :default => 'Löschen kann nicht rückgängig gemacht werden!')) },
:class => 'btn btn-xs btn-danger' %>
+ <% end %>
<%= link_to t('.new', :default => t('helpers.links.apply')),
new_application_letter_path(:event_id => event.id),
:class => 'btn btn-xs btn-primary' %>
@@ -38,6 +42,8 @@
|
-<%= link_to t('.new', :default => t('helpers.links.new')),
+<% if can? :new, Event %>
+ <%= link_to t('.new', :default => t('helpers.links.new')),
new_event_path,
:class => 'btn btn-primary' %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/profiles/index.html.erb b/app/views/profiles/index.html.erb
index 6450f242..a6975569 100644
--- a/app/views/profiles/index.html.erb
+++ b/app/views/profiles/index.html.erb
@@ -24,7 +24,7 @@
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
profile_path(profile),
:method => :delete,
- :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
+ :data => { :confirm => t('.confirm', :default => t("profiles.confirm_deletion", :default => 'Are you sure?')) },
:class => 'btn btn-xs btn-danger' %>
diff --git a/app/views/profiles/show.html.erb b/app/views/profiles/show.html.erb
index 9c44d4ae..951085f0 100644
--- a/app/views/profiles/show.html.erb
+++ b/app/views/profiles/show.html.erb
@@ -21,7 +21,7 @@
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
profile_path(@profile),
:method => 'delete',
- :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
+ :data => { :confirm => t('.confirm', :default => t("profiles.confirm_deletion", :default => 'Are you sure?')) },
:class => 'btn btn-danger' %>
Events
diff --git a/app/views/requests/index.html.erb b/app/views/requests/index.html.erb
index 1acb4c24..fabf72c2 100644
--- a/app/views/requests/index.html.erb
+++ b/app/views/requests/index.html.erb
@@ -20,19 +20,25 @@
<%= request.user_id %> |
<%=l request.created_at %> |
- <%= link_to t('.edit', :default => t("helpers.links.edit")),
+ <% if can? :edit, request %>
+ <%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_request_path(request), :class => 'btn btn-default btn-xs' %>
- <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
+ <% end %>
+ <% if can? :destroy, request %>
+ <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
request_path(request),
:method => :delete,
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-xs btn-danger' %>
+ <% end %>
|
<% end %>
-<%= link_to t('.new', :default => t("helpers.links.new")),
+<% if can? :new, Request %>
+ <%= link_to t('.new', :default => t("helpers.links.new")),
new_request_path,
:class => 'btn btn-primary' %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/requests/show.html.erb b/app/views/requests/show.html.erb
index ffe12b8b..72b328a2 100644
--- a/app/views/requests/show.html.erb
+++ b/app/views/requests/show.html.erb
@@ -12,10 +12,14 @@
<%= link_to t('.back', :default => t("helpers.links.back")),
requests_path, :class => 'btn btn-default' %>
-<%= link_to t('.edit', :default => t("helpers.links.edit")),
+<% if can? :edit, @request %>
+ <%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_request_path(@request), :class => 'btn btn-default' %>
-<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
+<% end %>
+<% if can? :destroy, @request %>
+ <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
request_path(@request),
:method => 'delete',
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-danger' %>
+<% end %>
diff --git a/config/locales/de.application_letters.yml b/config/locales/de.application_letters.yml
index 6c6e077a..4d9d25a6 100644
--- a/config/locales/de.application_letters.yml
+++ b/config/locales/de.application_letters.yml
@@ -14,7 +14,14 @@ de:
Programmierkenntnisse sind keine Voraussetzung zur Teilnahme. Diese Information
wird zur Gruppeneinteilung benötigt."
login_before_creation: "Du musst angemeldet sein, um dich für Workshops bewerben zu können."
+ successful_update: "Bewerbung erfolgreich bearbeitet"
+ successful_deletion: "Bewerbung erfolgreich gelöscht"
+ successful_creation: "Bewerbung erfolgreich erstellt"
fill_in_profile_before_creation: "Du musst erst dein Profil ausfüllen, um dich für Workshops bewerben zu können."
+ application_page:
+ title: "Bewerbung von %{name}"
+ for: "für %{event}"
+ confirm_deletion: "Willst du diese Bewerbung wirklich löschen?"
activerecord:
models:
@@ -40,4 +47,6 @@ de:
accepted: "Angenommen"
rejected: "Abgelehnt"
pending: "Ausstehend"
+ pending_before_deadline: "Beworben"
+ pending_after_deadline: "In Bearbeitung"
alternative: "Nachrücker"
diff --git a/config/locales/de.events.yml b/config/locales/de.events.yml
index c25ceb60..5fbfa63a 100644
--- a/config/locales/de.events.yml
+++ b/config/locales/de.events.yml
@@ -16,6 +16,8 @@ de:
occupied_places:
one: '%{count} Platz belegt'
other: '%{count} Plätze belegt'
+ print_all: "Alle ausdrucken"
+ accept_all: "Alle annehmen"
unclassified_applications_left: 'Bewerbung(en) wurden noch nicht klassifiziert'
maximum_number_of_participants_exeeded: 'Maximale Teilnehmeranzahl wurde überschritten'
sending_acceptances: 'Zusagen verschicken'
@@ -32,7 +34,6 @@ de:
unnecessary: "nicht benötigt"
available: "vorhanden"
unavailable: "nicht vorhanden"
-
kinds:
workshop: "Workshop"
camp: "Camp"
@@ -54,12 +55,18 @@ de:
add_timespan: "Zeitspanne hinzufügen"
email:
templates: "Vorlagen"
+ applications_pdf:
+ free_places: "Freie Plätze"
+ occupied_places: "Belegte Plätze"
+ page: "Seite"
errors:
application_deadline_before_start_of_event: "Bewerbungsschluss muss vor Beginn der Veranstaltung liegen"
activerecord:
models:
- event: "Veranstaltung"
+ event:
+ one: "Veranstaltung"
+ other: "Veranstaltungen"
attributes:
event:
name: "Name"
diff --git a/config/locales/de.profiles.yml b/config/locales/de.profiles.yml
index b54b9827..4d0b5380 100644
--- a/config/locales/de.profiles.yml
+++ b/config/locales/de.profiles.yml
@@ -10,6 +10,10 @@ de:
male: "Männlich"
female: "Weiblich"
other: "Andere"
+ confirm_deletion: "Willst du dieses Profil wirklich löschen?"
+ successful_update: "Profil erfolgreich aktualisiert"
+ successful_deletion: "Profil erfolgreich gelöscht"
+ successful_creation: "Profil erfolgreich erstellt"
activerecord:
models:
diff --git a/config/locales/de.users.yml b/config/locales/de.users.yml
index a6a7a6cb..49ad7922 100644
--- a/config/locales/de.users.yml
+++ b/config/locales/de.users.yml
@@ -4,5 +4,5 @@ de:
activerecord:
attributes:
user:
- accepted_application_count: "Anzahl der angenommenen Bewerbungen"
- rejected_application_count: "Anzahl der abgelehnten Bewerbungen"
+ accepted_application_count: "Angenommene Bewerbungen"
+ rejected_application_count: "Abgelehnte Bewerbungen"
diff --git a/config/routes.rb b/config/routes.rb
index f5688550..b6cd569f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,12 +3,16 @@
get 'agreement_letters/show'
resources :requests
+
+ put 'applications/:id/status' => 'application_letters#update_status', as: :update_application_letter_status
+
resources :application_letters, path: 'applications' do
resources :application_notes,
only: :create
end
resources :events do
resources :agreement_letters, only: [:create], shallow: true
+ get 'print_applications', on: :member
get 'badges'
post 'badges' => 'events#print_badges', as: :print_badges
end
diff --git a/db/sample_data.rb b/db/sample_data.rb
new file mode 100644
index 00000000..5d2e0ea7
--- /dev/null
+++ b/db/sample_data.rb
@@ -0,0 +1,74 @@
+require './db/sample_data/agreement_letters'
+require './db/sample_data/application_letters'
+require './db/sample_data/events'
+require './db/sample_data/profiles'
+require './db/sample_data/requests'
+require './db/sample_data/users'
+
+def add_sample_data
+ events = Hash.new
+
+ events[:programmierkurs] = event_programmierkurs
+ events[:mintcamp] = event_mintcamp
+ events[:bechersaeuberungsevent] = event_bechersaeuberungsevent
+ events[:gongakrobatik] = event_gongakrobatik
+ events[:batterie_akustik] = event_batterie_akustik
+ events[:bachlorpodium] = event_bachlorpodium
+ events[:past_deadline_event] = event_gongakrobatik
+
+ users = Hash.new
+ users[:pupil] = user_pupil
+ users[:teacher] = user_teacher
+ users[:applicant] = user_applicant
+ users[:tobi] = user_tobi
+ users[:lisa] = user_lisa
+ users[:max] = user_max
+ users[:organizer] = user_organizer
+ users[:coach] = user_coach
+
+ profiles = Hash.new
+ profiles[:pupil] = profile_pupil(users[:pupil])
+ profiles[:teacher] = profile_teacher(users[:teacher])
+ profiles[:applicant] = profile_applicant(users[:applicant])
+
+ profiles[:tobi] = profile_tobi(users[:tobi])
+ profiles[:tobi] = profile_tobi(users[:tobi])
+ profiles[:lisa] = profile_lisa(users[:lisa])
+ profiles[:max] = profile_pupil_max(users[:max])
+ profiles[:organizer] = profile_pupil_max(users[:organizer])
+ profiles[:coach] = profile_pupil_max(users[:coach])
+
+ application_letters = Hash.new
+ application_letters[:applicant_gongakrobatik] = application_letter_applicant_gongakrobatik(users[:applicant], events[:gongakrobatik])
+ application_letters[:applicant_gongakrobatik_past_deadline] = application_letter_applicant_gongakrobatik(users[:applicant], events[:past_deadline_event])
+ application_letters[:applicant_gongakrobatik_accepcted] = application_letter_applicant_gongakrobatik_accepted(users[:applicant], events[:past_deadline_event])
+ application_letters[:applicant_gongakrobatik_rejected] = application_letter_applicant_gongakrobatik_rejected(users[:applicant], events[:past_deadline_event])
+ application_letters[:applicant_programmierkurs_lisa] = application_letter_applicant_programmierkurs_1(users[:lisa], events[:programmierkurs])
+ application_letters[:applicant_programmierkurs_max] = application_letter_applicant_programmierkurs_2(users[:max], events[:programmierkurs])
+ application_letters[:applicant_programmierkurs_tobi] = application_letter_applicant_programmierkurs_3(users[:tobi], events[:programmierkurs])
+
+ application_letters[:applicant_mintcamp_lisa] = application_letter_applicant_programmierkurs_1(users[:lisa], events[:mintcamp])
+ application_letters[:applicant_mintcamp_max] = application_letter_applicant_programmierkurs_2(users[:max], events[:mintcamp])
+ application_letters[:applicant_mintcamp_tobi] = application_letter_applicant_programmierkurs_3(users[:tobi], events[:mintcamp])
+
+ requests = Hash.new
+ requests[:hardware_entwicklung] = request_hardware_entwicklung(users[:teacher])
+
+ agreement_letters = Hash.new
+ agreement_letters[:applicant_gongakrobatik] = agreement_letter_applicant_gongakrobatik(users[:applicant], events[:gongakrobatik])
+
+ [events, users, profiles, application_letters, requests, agreement_letters].each do |models|
+ save_models(models)
+ end
+
+ # set deadline to past to work around validation of application letters
+ events[:past_deadline_event].application_deadline = Date.yesterday
+ events[:past_deadline_event].save!
+end
+
+private
+ def save_models(models)
+ models.each do |key, model|
+ model.save!
+ end
+ end
diff --git a/db/sample_data/agreement_letters.rb b/db/sample_data/agreement_letters.rb
new file mode 100644
index 00000000..2f558914
--- /dev/null
+++ b/db/sample_data/agreement_letters.rb
@@ -0,0 +1,7 @@
+def agreement_letter_applicant_gongakrobatik(user, event)
+ AgreementLetter.new(
+ user: user,
+ event: event,
+ path: "/storage/agreement_letters/foo.pdf"
+ )
+end
\ No newline at end of file
diff --git a/db/sample_data/application_letters.rb b/db/sample_data/application_letters.rb
new file mode 100644
index 00000000..51ee71cf
--- /dev/null
+++ b/db/sample_data/application_letters.rb
@@ -0,0 +1,98 @@
+def application_letter_applicant_gongakrobatik(user, event)
+ ApplicationLetter.new(
+ motivation: "Ich habe vor kurzem davon erfahren und war direkt hellaufbegeistert. Gerne würde ich mich bei Ihnen näher über das Thema informieren",
+ grade: 10,
+ experience: "Über einen Facebookpost ihrer Seite bin ich auf das Angebot aufmerksam geworden",
+ coding_skills: "HTML",
+ emergency_number: "01234567891",
+ vegeterian: false,
+ vegan: false,
+ allergic: false,
+ allergies: "",
+ user: user,
+ event: event
+ )
+end
+
+def application_letter_applicant_gongakrobatik_rejected(user, event)
+ ApplicationLetter.new(
+ motivation: "Ich habe vor kurzem davon erfahren und war direkt hellaufbegeistert. Gerne würde ich mich bei Ihnen näher über das Thema informieren",
+ grade: 10,
+ experience: "Über einen Facebookpost ihrer Seite bin ich auf das Angebot aufmerksam geworden",
+ coding_skills: "HTML",
+ emergency_number: "01234567891",
+ vegeterian: false,
+ vegan: false,
+ allergic: false,
+ allergies: "",
+ user: user,
+ event: event,
+ status: ApplicationLetter.statuses[:rejected]
+ )
+end
+
+def application_letter_applicant_gongakrobatik_accepted(user, event)
+ ApplicationLetter.new(
+ motivation: "Den normalen Unterricht in der Schule finde ich ziemlich langweilig und würde mich darüber freuen, etwas über den Tellerrand zu schauen und spannende Dinge lernen. Ich arbeite sehr gerne im Team und freue mich darauf, Gleichgesinnte kennen zu lernen.",
+ grade: 9,
+ experience: "Über einen Zeitungsartikel",
+ coding_skills: "For, While und If-Schleifen in Java",
+ emergency_number: "01234567891",
+ vegeterian: false,
+ vegan: false,
+ allergic: true,
+ allergies: "Tomaten",
+ user: user,
+ event: event,
+ status: ApplicationLetter.statuses[:accepted]
+ )
+end
+
+def application_letter_applicant_programmierkurs_1(user, event)
+ ApplicationLetter.new(
+ motivation: "Den normalen Unterricht in der Schule finde ich ziemlich langweilig und würde mich darüber freuen, etwas über den Tellerrand zu schauen und spannende Dinge lernen. Ich arbeite sehr gerne im Team und freue mich darauf, Gleichgesinnte kennen zu lernen.",
+ grade: 9,
+ experience: "Über einen Zeitungsartikel",
+ coding_skills: "For, While und If-Schleifen in Java",
+ emergency_number: "01234567891",
+ vegeterian: false,
+ vegan: false,
+ allergic: true,
+ allergies: "Tomaten",
+ user: user,
+ event: event
+ )
+end
+
+def application_letter_applicant_programmierkurs_2(user, event)
+ ApplicationLetter.new(
+ motivation: "Ich habe vor kurzem davon erfahren und war direkt hellaufbegeistert. Gerne würde ich mich bei Ihnen näher über das Thema informieren",
+ grade: 10,
+ experience: "Suche im Internet",
+ coding_skills: "keine",
+ emergency_number: "01234567891",
+ vegeterian: true,
+ vegan: false,
+ allergic: false,
+ allergies: "",
+ user: user,
+ event: event
+ )
+end
+
+def application_letter_applicant_programmierkurs_3(user, event)
+ ApplicationLetter.new(
+ motivation: "Ich habe vor LANGEM davon erfahren und war direkt hellaufbegeistert. Gerne würde ich mich bei Ihnen
+näher über das Thema informieren",
+ grade: 10,
+ experience: "Suche im Internetz",
+ coding_skills: "absolut keine",
+ emergency_number: "01234567819",
+ vegeterian: true,
+ vegan: false,
+ allergic: false,
+ allergies: "",
+ user: user,
+ event: event
+ )
+end
\ No newline at end of file
diff --git a/db/sample_data/events.rb b/db/sample_data/events.rb
new file mode 100644
index 00000000..ca57bbae
--- /dev/null
+++ b/db/sample_data/events.rb
@@ -0,0 +1,136 @@
+def event_programmierkurs
+ date_range_singleday = DateRange.create!(
+ start_date: Date.new(2017, 05, 04),
+ end_date: Date.new(2017, 05, 05)
+ )
+
+ Event.new(
+ name: 'Android Programmierkurs',
+ description: 'Ihr wolltet schon immer einmal eine eigene App programmieren? In diesem Workshop lernt ihr object-orientierte Programmierung am Beispiel von einer Android App.',
+ max_participants: 25,
+ organizer: 'HPI Schülerklub',
+ knowledge_level: 'Anfänger',
+ date_ranges: [date_range_singleday],
+ application_deadline: Date.tomorrow,
+ draft: false,
+ application_status_locked: false
+ )
+end
+
+def event_mintcamp
+ date_range_mint_camp = DateRange.create!(
+ start_date: Date.new(2017, 03, 30),
+ end_date: Date.new(2017, 04, 04)
+ )
+
+ Event.new(
+ name: 'MINT-Camp',
+ description: 'Wie soll die digitale Zukunft in den Schulen aussehen? In immer mehr Schulen kommen Smartboards zum Einsatz. Diese elektronischen Tafeln haben das Potenzial den Unterricht und das Lernen nachhaltig zu verbessern. Häufig wird das Gerät allerdings auf seinen älteren Verwandten reduziert und nur zum Schreiben, bestenfalls auch für die Medienwiedergabe genutzt. Der Grund dafür sind meist schwer verständliche Programme, die weder die Bedürfnisse der Schüler noch die der Lehrer erfüllen. Dabei sind weitaus interessantere und vor allem sinnvollere Anwendungen für die intelligenten Tafeln denkbar. In diesem MINT-Camp entwickeln wir in kleinen Teams zunächst mit Hilfe von Design Thinking spannende neuartige Ideen für Smartboards. Anschließend werden die Ideen mit Webtechnologien implementiert und können direkt ausprobiert werden. Zum Abschluss hat jedes Team die Möglichkeit seine fertig entwickelte Anwendung zu präsentieren. Dabei stehen euch die ganze Zeit HPI-Studenten zur Seite und helfen euch bei Problemen aller Art. Vorkenntnisse sind keine erforderlich. ',
+ max_participants: 25,
+ organizer: 'HPI Schülerklub',
+ knowledge_level: 'Fortgeschrittene',
+ date_ranges: [date_range_mint_camp],
+ application_deadline: Date.tomorrow,
+ draft: false,
+ application_status_locked: false
+ )
+end
+
+def event_bechersaeuberungsevent
+ date_range_singleday = DateRange.create!(
+ start_date: Date.new(2017, 04, 04),
+ end_date: Date.new(2017, 04, 05)
+ )
+ Event.new(
+ name: 'Bechersäuberungsevent',
+ description: 'Es dreht sich den ganzen Tag um das Säubern von Bechern. Wie säubert man einen Becher am
+effizientesten oder am schnellsten? Wie immer bieten wir eine Reihe an Expertenvorträgen an. Dieses Mal erfahrt ihr
+unter anderem wie ihr Edding-Markierungen selbst nach einer Spülmaschinen-Reinigung noch entfernen könnt oder wie man
+die richtige Größe für Becher-Stapel herausfindet und anwendet.',
+ max_participants: 25,
+ organizer: 'FSR',
+ knowledge_level: 'Anfänger',
+ date_ranges: [date_range_singleday],
+ application_deadline: Date.tomorrow,
+ draft: false,
+ application_status_locked: false
+ )
+end
+
+def event_gongakrobatik
+ date_range_long = DateRange.create!(
+ start_date: Date.new(2020, 02, 29),
+ end_date: Date.new(2021, 03, 05)
+ )
+ Event.new(
+ name: 'Einführung in die Kunst der Gongakrobatik',
+ description: 'Schon im alten China erzählte man sich von den sagenumwobenen Legenden der Gongakrobatik.
+Spätestens seit dieser Trend auch seinen Weg nach Japan gefunden hat, stellt sich die Gongakrobatik auch für uns als
+ernstzunehmende Alternative gegenüber herkömmlichen Stimmbildungübungen und ähnlichem dar. In dieser Einführung möchten
+wir euch einen groben Überblick über das Thema geben: Wie findet man am besten seinen Weg in die Gongakrobatik, was
+braucht man dafür. In den letzten Jahren hat sich zudem eine große Community rund um dieses faszinierende Thema gebildet.
+Höhepunkt der Veranstaltung ist demnach unser Besuch einer echten Gongmanufaktor im Herzen Berlins, durchgeführt von dem
+Ding Gong-Verein Berlin. Bei Bedarf können wir eine zweite Veranstaltung durchführen, bis dahin gilt first come first serve :)',
+ max_participants: 19,
+ knowledge_level: 'Ihr braucht kein besonderes Vorwissen, jeder ist Willkommen!',
+ date_ranges: [date_range_long],
+ application_deadline: Date.tomorrow,
+ draft: false,
+ application_status_locked: false
+ )
+end
+
+def event_batterie_akustik
+ date_range_short = DateRange.create!(
+ start_date: Date.tomorrow.next_day(3),
+ end_date: Date.tomorrow.next_day(5)
+ )
+
+ date_range_medium = DateRange.create!(
+ start_date: Date.new(2017, 06, 01),
+ end_date: Date.new(2017, 06, 14)
+ )
+ Event.new(
+ name: 'Batterie-Akustik für Fortgeschrittene',
+ description: 'Viele Menschen sammeln bereits im jungen Alter Erfahrung mit der überaus komplexen Batterie-Akustik.
+"Leider wird daraus bei vielen aber nicht mehr als bloßes Jugendwissen, das sich höchstens für den jährlichen Party-Gag
+eignet" erklärt Dr. Warta Durazell vom Institut für Angewandte Batterie-Akustik (IAB). Mit dieser Workshop-Serie möchten
+wir etwas an diesem Missstand ändern. Wie viele Batterien werden benötigt um einen Echo-Effekt gleichwertig zum
+Akkumulator-Echo zu erzeugen? Ist dies überhaupt außerhalb von Laborbedingungen möglich? Die Teilnehmer haben nach den
+Veranstaltungen ein fundiertes Wissen über die Klangeigenschaften sowie das (nicht äquivalente) Klangverhalten von
+Batterien. Zudem erhalten sie ein offizielles Zertifikat des IAB, welches es ihnen ermöglicht an weiterführenden
+Veranstaltungen zum Thema teilzunehmen. Gerade in Zeit von E-Autos ist dies ein wichtiges Alleinstellungsmerkmal auf dem
+Arbeitsmarkt. Bitte beachtet die maximale Teilnehmeranzahl! Wichtig: Es gilt first come last served.',
+ max_participants: 32,
+ organizer: 'IAB',
+ date_ranges: [date_range_short, date_range_medium],
+ application_deadline: Date.tomorrow,
+ draft: false,
+ application_status_locked: false
+ )
+end
+
+def event_bachlorpodium
+ date_range_singleday1 = DateRange.create!(
+ start_date: Date.tomorrow,
+ end_date: Date.tomorrow
+ )
+ date_range_singleday2 = DateRange.create!(
+ start_date: Date.new(2017, 04, 04),
+ end_date: Date.new(2017, 04, 05)
+ )
+ date_range_singleday3 = DateRange.create!(
+ start_date: Date.new(2017, 04, 06),
+ end_date: Date.new(2017, 04, 06)
+ )
+ Event.new(
+ name: 'Bachelorpodium',
+ description: 'Trotz modernem Videostreaming in HD in die anderen Hörsäle bleibt Hörsaal 1 doch der Publikumsliebling
+bei diesem jährlich mit größter Sorgfalt organisierten spektakulären PR Gag',
+ max_participants: 442,
+ date_ranges: [date_range_singleday1, date_range_singleday2, date_range_singleday3],
+ application_deadline: Date.tomorrow,
+ draft: false,
+ application_status_locked: false
+ )
+end
diff --git a/db/sample_data/profiles.rb b/db/sample_data/profiles.rb
new file mode 100644
index 00000000..7d9d2d61
--- /dev/null
+++ b/db/sample_data/profiles.rb
@@ -0,0 +1,101 @@
+def profile_pupil(user)
+ Profile.new(
+ user: user,
+ first_name: "Karl",
+ last_name: "Doe",
+ gender: "male",
+ birth_date: Date.parse('2000.11.29'),
+ school: "Schule am Griebnitzsee",
+ street_name: "Rudolf-Breitscheid-Str. 52",
+ zip_code: "14482",
+ city: "Potsdam",
+ state: "Brandenburg",
+ country: "Deutschland",
+ graduates_school_in: "2019"
+ )
+end
+
+def profile_pupil_max(user)
+ Profile.new(
+ user: user,
+ first_name: "Max",
+ last_name: "Mustermann",
+ gender: "male",
+ birth_date: Date.parse('2000.12.09'),
+ school: "Musterschule",
+ street_name: "Musterstraße 42",
+ zip_code: "14482",
+ city: "Potsdam",
+ state: "Brandenburg",
+ country: "Deutschland",
+ graduates_school_in: "2018"
+ )
+end
+
+def profile_teacher(user)
+ Profile.new(
+ user: user,
+ first_name: "Ernst",
+ last_name: "Teacher",
+ gender: "male",
+ birth_date: Date.parse('1970.1.1'),
+ school: "Schule am Griebnitzsee",
+ street_name: "Domstraße 14",
+ zip_code: "14482",
+ city: "Potsdam",
+ state: "Brandenburg",
+ country: "Deutschland",
+ graduates_school_in: "Bereits Abitur"
+ )
+end
+
+def profile_applicant(user)
+ Profile.new(
+ user: user,
+ first_name: "Erika",
+ last_name: "Mustermann",
+ gender: "female",
+ birth_date: Date.parse('1999.08.14'),
+ school: "Schule am Griebnitzsee",
+ street_name: "Rudolf-Breitscheid-Str. 52",
+ zip_code: "14482",
+ city: "Potsdam",
+ state: "Brandenburg",
+ country: "Deutschland",
+ graduates_school_in: "2017"
+ )
+end
+
+def profile_tobi(user)
+ Profile.new(
+ user: user,
+ first_name: "Tobias",
+ last_name: "Dürschmid",
+ gender: "male",
+ birth_date: Date.parse('1995.08.31'),
+ school: "Goetheschule Ilmenau",
+ street_name: "Stahnsdorfer Str.",
+ zip_code: "14482",
+ city: "Potsdam",
+ state: "Brandenburg",
+ country: "Deutschland",
+ graduates_school_in: "Bereits Abitur"
+ )
+end
+
+def profile_lisa(user)
+ Profile.new(
+ user: user,
+ first_name: "Lisa",
+ last_name: "Ihde",
+ gender: "female",
+ birth_date: Date.parse('1996.09.21'),
+ school: "Sophie-Scholl-Gymnasium",
+ street_name: "Stahnsdorfer Str.",
+ zip_code: "14482",
+ city: "Potsdam",
+ state: "Brandenburg",
+ country: "Deutschland",
+ graduates_school_in: "Bereits Abitur"
+ )
+end
\ No newline at end of file
diff --git a/db/sample_data/requests.rb b/db/sample_data/requests.rb
new file mode 100644
index 00000000..f36e9cb4
--- /dev/null
+++ b/db/sample_data/requests.rb
@@ -0,0 +1,6 @@
+def request_hardware_entwicklung(user)
+ Request.new(
+ topics: "Hardware-Entwicklung mit einem CAD-System",
+ user: user
+ )
+end
\ No newline at end of file
diff --git a/db/sample_data/users.rb b/db/sample_data/users.rb
new file mode 100644
index 00000000..c760f8db
--- /dev/null
+++ b/db/sample_data/users.rb
@@ -0,0 +1,75 @@
+def user_password
+ "123456"
+end
+
+def user_pupil
+ User.new(
+ name: "Schueler",
+ email: "schueler@example.com",
+ password: user_password,
+ role: :pupil
+ )
+end
+
+def user_teacher
+ User.new(
+ name: "Lehrer",
+ email: "lehrer@example.com",
+ password: user_password,
+ role: :teacher
+ )
+end
+
+def user_applicant
+ User.new(
+ name: "Bewerber",
+ email: "bewerber@example.com",
+ password: user_password,
+ role: :pupil
+ )
+end
+
+def user_max
+ User.new(
+ name: "Max Mustermann",
+ email: "max@schueler.com",
+ password: user_password,
+ role: :pupil
+ )
+end
+
+def user_lisa
+ User.new(
+ name: "Lisa Ihde",
+ email: "lisa@schueler.com",
+ password: user_password,
+ role: :pupil
+ )
+end
+
+def user_tobi
+ User.new(
+ name: "Tobias Dürschmid",
+ email: "tobias.duerschmid@t-online.de",
+ password: user_password,
+ role: :pupil
+ )
+end
+
+def user_organizer
+ User.new(
+ name: "Organizer",
+ email: "organizer@workshops.hpi.de",
+ password: user_password,
+ role: :admin
+ )
+end
+
+def user_coach
+ User.new(
+ name: "Coach",
+ email: "coach@workshops.hpi.de",
+ password: user_password,
+ role: :coach
+ )
+end
\ No newline at end of file
diff --git a/db/seeds.rb b/db/seeds.rb
index 15360e37..9ede90eb 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -2,123 +2,13 @@
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
-# Users
-users = []
-pupil = User.find_or_initialize_by(
- name: "Schueler",
- email: "schueler@example.com"
+# Create Superuser
+admin = User.find_or_initialize_by(
+ name: "admin",
+ email: "info@domain.com",
+ role: :admin
)
-users.push(pupil)
+admin.password = "system"
+admin.save!
-teacher = User.find_or_initialize_by(
- name: "Lehrer",
- email: "lehrer@example.com"
-)
-users.push(teacher)
-
-applicant = User.find_or_initialize_by(
- name: "Bewerber",
- email: "bewerber@example.com"
-)
-users.push(applicant)
-
-# Set a password for every user
-# They are only initialized, save them to the db
-users.each do |user|
- user.password = "123456"
- user.save!
-end
-
-date_range = DateRange.find_or_create_by!(
- start_date: Date.tomorrow.next_day(3),
- end_date: Date.tomorrow.next_day(5)
-)
-
-# An event
-event = Event.new(
- name: "Messung und Verarbeitung von Umweltdaten",
- description: "Veranstaltung mit Phidgets und Etoys",
- max_participants: 20,
- application_deadline: Date.tomorrow,
- draft: false,
- application_status_locked: false
-)
-event.date_ranges << date_range
-event.save
-
-# Pupil's profile
-Profile.find_or_create_by!(
- user: pupil,
- first_name: "Karl",
- last_name: "Doe",
- gender: "male",
- birth_date: Date.parse('2000.11.29'),
- school: "Schule am Griebnitzsee",
- street_name: "Rudolf-Breitscheid-Str. 52",
- zip_code: "14482",
- city: "Potsdam",
- state: "Brandenburg",
- country: "Deutschland",
- graduates_school_in: "2019"
-)
-
-# Teacher's profile
-Profile.find_or_create_by!(
- user: teacher,
- first_name: "Ernst",
- last_name: "Teacher",
- gender: "male",
- birth_date: Date.parse('1970.1.1'),
- school: "Schule am Griebnitzsee",
- street_name: "Domstraße 14",
- zip_code: "14482",
- city: "Potsdam",
- state: "Brandenburg",
- country: "Deutschland",
- graduates_school_in: "Bereits Abitur"
-)
-
-# Applicant's profile
-Profile.find_or_create_by!(
- user: applicant,
- first_name: "Erika",
- last_name: "Mustermann",
- gender: "female",
- birth_date: Date.parse('1999.08.14'),
- school: "Schule am Griebnitzsee",
- street_name: "Rudolf-Breitscheid-Str. 52",
- zip_code: "14482",
- city: "Potsdam",
- state: "Brandenburg",
- country: "Deutschland",
- graduates_school_in: "2017"
-)
-
-# Teacher's event request
-Request.find_or_create_by!(
- topics: "Hardware-Entwicklung mit einem CAD-System",
- user: teacher
-)
-
-# Applicant's application letter
-ApplicationLetter.find_or_create_by!(
- motivation: "Ich würde sehr gerne an eurer Veranstaltung teilnehmen",
- grade: 10,
- experience: "Internet",
- coding_skills: "HTML",
- emergency_number: "01234567891",
- vegeterian: false,
- vegan: false,
- allergic: false,
- allergies: "",
- status: ApplicationLetter.statuses[:pending],
- user: applicant,
- event: event
-)
-
-AgreementLetter.find_or_create_by!(
- user: applicant,
- event: event,
- path: "/storage/agreement_letters/foo.pdf"
-)
diff --git a/lib/pdf_generation/applications_pdf.rb b/lib/pdf_generation/applications_pdf.rb
new file mode 100644
index 00000000..b1e70608
--- /dev/null
+++ b/lib/pdf_generation/applications_pdf.rb
@@ -0,0 +1,158 @@
+class ApplicationsPDF
+ include Prawn::View
+ Prawn::Font::AFM.hide_m17n_warning = true #consider adding TTF font
+
+ # Generates a PDF file containing the details of every application for an event
+ #
+ # param event [Event] the event whose applications are taken
+ # return [String] the generated PDF
+ def self.generate(event)
+ self.new(event).create.render
+ end
+
+ def initialize(event)
+ @event = event
+ @document = Prawn::Document.new(page_size: 'A4')
+ @application_letters_count = @event.application_letters.count
+ end
+
+ # Adds all necessary data and formatting to the ApplicationsPDF
+ #
+ # param none
+ # return [ApplicationsPDF] self
+ def create
+ create_overview
+ @event.application_letters.each_with_index do |a,i|
+ create_application_page(a, i)
+ end
+ self
+ end
+
+ private
+ def create_overview
+ text t("events.applicants_overview.title", title: @event.name), size: 20
+ table description_table_data do
+ cells.borders = []
+ cells.padding = 3
+ column(0).font_style = :bold
+ column(0).align = :right
+ end
+ unless @event.application_letters.empty?
+ table overview_table_data,
+ header: 2, position: :center, row_colors: ["F9F9F9", "FFFFFF"] do
+ cells.borders = []
+ row(1).borders = [:bottom]
+ row(1).font_style = :bold
+ row(0).font_style = :bold
+ row(0).padding = [5, 0, 5, 5] #minimize padding between first two rows
+ row(1).padding = [0, 5, 5, 5]
+ end
+ end
+ end
+
+ def description_table_data
+ data = [[Event.human_attribute_name(:description)+":", @event.description],
+ [Event.human_attribute_name(:max_participants) + ":", @event.max_participants],
+ [Event.human_attribute_name(:date_ranges) + ":", @event.date_ranges[0].to_s]]
+ data += @event.date_ranges.drop(1).map { |d| ["", d.to_s] }
+ data += [[Event.human_attribute_name(:organizer) + ":", @event.organizer]] if @event.organizer
+ data += [[Event.human_attribute_name(:knowledge_level) + ":", @event.knowledge_level]] if @event.knowledge_level
+ data += [[t("events.applications_pdf.free_places") + ":", @event.compute_free_places],
+ [t("events.applications_pdf.occupied_places") + ":", @event.compute_occupied_places]]
+ end
+
+ def overview_table_data
+ #line breaks lead to weird table formatting, so we create 2 header rows to fit all the text
+ data = [["", "", "", t("events.applicants_overview.participations"), ""]]
+ data += [[Profile.human_attribute_name(:name),
+ Profile.human_attribute_name(:gender),
+ Profile.human_attribute_name(:age),
+ t("events.applicants_overview.accepted_rejected"),
+ ApplicationLetter.human_attribute_name(:status)]]
+ data += @event.application_letters.map do |a|
+ [a.user.profile.name,
+ a.user.profile.gender,
+ a.user.profile.age,
+ "#{a.user.accepted_applications_count(@event)} / #{a.user.rejected_applications_count(@event)}",
+ t("application_status.#{a.status}")]
+ end
+ end
+
+ def create_application_page(application_letter, index)
+ start_new_page
+ first_page = page_number
+ create_main_header(application_letter)
+
+ bounding_box([bounds.left, bounds.top - 50],
+ width: bounds.width,
+ height: bounds.height - 100) do
+ create_application_page_content(application_letter)
+ end
+
+ create_headers(application_letter, first_page, page_number)
+ create_footers(index, first_page, page_number)
+ end
+
+ def create_application_page_content(application_letter)
+ table applicants_detail_data(application_letter) do
+ cells.borders = []
+ cells.padding = 3
+ column(0).font_style = :bold
+ column(0).align = :right
+ end
+ pad_top(20) { text "
#{ApplicationLetter.human_attribute_name(:motivation)}", inline_format: true}
+ pad_top(5) { text application_letter.motivation }
+ unless application_letter.application_notes.count == 0
+ pad_top(15) do
+ text "
#{ApplicationNote.model_name.human(count: application_letter.application_notes.count)}", inline_format: true
+ application_letter.application_notes.each do |note|
+ pad_top(5) { text note.note }
+ end
+ end
+ end
+ end
+
+ def applicants_detail_data(application_letter)
+ [[Profile.human_attribute_name(:gender)+":", application_letter.user.profile.gender],
+ [Profile.human_attribute_name(:age)+":", application_letter.user.profile.age],
+ [Profile.human_attribute_name(:address)+":", application_letter.user.profile.address],
+ [User.human_attribute_name(:accepted_application_count)+":", application_letter.user.accepted_applications_count(@event)],
+ [User.human_attribute_name(:rejected_application_count)+":", application_letter.user.rejected_applications_count(@event)],
+ [Profile.human_attribute_name(:status)+":", t("application_status.#{application_letter.status}")]]
+ end
+
+ def create_main_header(application_letter)
+ text t("application_letters.application_page.title", name: application_letter.user.profile.name), size: 20
+ text t("application_letters.application_page.for", event: @event.name), size: 14
+ stroke_horizontal_rule
+ end
+
+ def create_headers(application_letter, first_page, last_page)
+ repeat(first_page + 1..last_page) do
+ bounding_box [bounds.left, bounds.top], width: bounds.width do
+ text @event.name
+ text_box application_letter.user.profile.name, align: :right
+ stroke_horizontal_rule
+ end
+ end
+ end
+
+ def create_footers(index, first_page, last_page)
+ repeat(first_page..last_page, dynamic: true) do
+ bounding_box [bounds.left, bounds.bottom + 25], width: bounds.width do
+ relative_page = page_number - first_page + 1
+ relative_last_page = last_page - first_page + 1
+ stroke_horizontal_rule
+ move_down(5)
+ text_box(t("events.applications_pdf.page") + " #{relative_page}/#{relative_last_page}",
+ at: [0, cursor],
+ align: :right)
+ text ApplicationLetter.model_name.human + " #{index + 1}/#{@application_letters_count}"
+ end
+ end
+ end
+
+ def t(string, options = {})
+ I18n.t(string, options)
+ end
+end
diff --git a/lib/tasks/sample_data.rake b/lib/tasks/sample_data.rake
new file mode 100644
index 00000000..1421a6d3
--- /dev/null
+++ b/lib/tasks/sample_data.rake
@@ -0,0 +1,8 @@
+require './db/sample_data'
+
+namespace :db do
+ desc 'Populates the database with sample data'
+ task populate_sample_data: :environment do
+ add_sample_data
+ end
+end
\ No newline at end of file
diff --git a/spec/controllers/application_letters_controller_spec.rb b/spec/controllers/application_letters_controller_spec.rb
index 4d5feaad..19ee27ee 100644
--- a/spec/controllers/application_letters_controller_spec.rb
+++ b/spec/controllers/application_letters_controller_spec.rb
@@ -78,8 +78,7 @@
vegeterian: true,
vegan: true,
allergic: true,
- allergys: "Many",
- status: "accepted"
+ allergys: "Many"
}
}
@@ -87,7 +86,6 @@
put :update, id: @application.to_param, application_letter: new_attributes, session: valid_session
@application.reload
expect(@application.motivation).to eq(new_attributes[:motivation])
- expect(@application.status).to eq(new_attributes[:status])
end
it "assigns the requested application as @application" do
@@ -114,6 +112,43 @@
end
end
+ describe "PUT #update_status" do
+ before :each do
+ sign_in FactoryGirl.create(:user, role: :admin)
+ end
+ context "with valid params" do
+ let(:new_status) { {status: 'accepted'} }
+
+ it "assigns the requested application as @application" do
+ put :update_status, id: @application.to_param, application_letter: new_status, session: valid_session
+ expect(assigns(:application_letter)).to eq(@application)
+ end
+
+ it "updates the status" do
+ put :update_status, id: @application.to_param, application_letter: new_status, session: valid_session
+ @application.reload
+ expect(@application.status).to eq(new_status[:status])
+ end
+
+ it "redirects back" do
+ put :update_status, id: @application.to_param, application_letter: new_status, session: valid_session
+ expect(response).to redirect_to(request.env['HTTP_REFERER'])
+ end
+ end
+
+ context "with invalid params" do
+ it "assigns the application as @application" do
+ put :update_status, id: @application.to_param, application_letter: {status: nil}, session: valid_session
+ expect(assigns(:application_letter)).to eq(@application)
+ end
+
+ it "re-renders the 'edit' template" do
+ put :update_status, id: @application.to_param, application_letter: {status: nil}, session: valid_session
+ expect(response).to render_template("edit")
+ end
+ end
+ end
+
describe "DELETE #destroy" do
it "destroys the requested application" do
expect {
@@ -163,4 +198,4 @@
end
end
end
-end
\ No newline at end of file
+end
diff --git a/spec/controllers/events_controller_spec.rb b/spec/controllers/events_controller_spec.rb
index 59e7d11d..50726465 100644
--- a/spec/controllers/events_controller_spec.rb
+++ b/spec/controllers/events_controller_spec.rb
@@ -256,4 +256,79 @@
expect(assigns(:event).date_ranges.first.end_date).to eq(date_range.end_date)
end
end
+
+ describe "GET #print_applications" do
+ before :each do
+ @event = Event.create! valid_attributes
+ @user = FactoryGirl.create(:user, role: :organizer)
+ sign_in @user
+ end
+
+ it "returns success" do
+ get :print_applications, id: @event.to_param, session: valid_session
+ expect(response).to be_success
+ end
+
+ it 'returns downloadable PDF' do
+ get :print_applications, id: @event.to_param, session: valid_session
+ PDF::Inspector::Text.analyze response.body
+ end
+
+ it "returns a PDF with a correct overview page" do
+ get :print_applications, id: @event.to_param, session: valid_session
+ page_analysis = PDF::Inspector::Page.analyze(response.body)
+ expect(page_analysis.pages.size).to be 1
+ analysis = PDF::Inspector::Text.analyze response.body
+ text = analysis.strings.join
+ expect(text).to include(
+ @event.name,
+ @event.max_participants.to_s,
+ @event.organizer,
+ @event.knowledge_level,
+ @event.compute_free_places.to_s,
+ @event.compute_occupied_places.to_s)
+ @event.date_ranges.each { |d| expect(text).to include(d.to_s) }
+ end
+
+ it "shows an overview of all and details of every application" do
+ al = FactoryGirl.create(:application_letter, event: @event,)
+ FactoryGirl.create(:application_note, application_letter_id: al.id)
+ User.find_each { |u| FactoryGirl.create(:profile, user: u) }
+ get :print_applications, id: @event.to_param, session: valid_session
+ analysis = PDF::Inspector::Text.analyze response.body
+ text = analysis.strings.join(' ')
+ @event.application_letters.each do |a|
+ expect(text).to include(
+ a.user.profile.name,
+ a.user.profile.age.to_s,
+ a.user.profile.gender,
+ a.user.accepted_applications_count(@event).to_s,
+ a.user.rejected_applications_count(@event).to_s,
+ I18n.t("application_status.#{a.status}"),
+ a.user.profile.address,
+ a.motivation
+ )
+ a.application_notes.each do |note|
+ expect(text).to include(note.note)
+ end
+ end
+ end
+
+ it "includes at last one page per application" do
+ FactoryGirl.create(:application_letter, event: @event,)
+ FactoryGirl.create(:application_letter2, event: @event,)
+ User.find_each { |u| FactoryGirl.create(:profile, user: u) }
+ get :print_applications, id: @event.to_param, session: valid_session
+ page_analysis = PDF::Inspector::Page.analyze(response.body)
+ expect(page_analysis.pages.size).to be >= 3
+ end
+
+ it "extends long applications over several pages" do
+ FactoryGirl.create(:application_letter_long, event: @event,)
+ User.find_each { |u| FactoryGirl.create(:profile, user: u) }
+ get :print_applications, id: @event.to_param, session: valid_session
+ page_analysis = PDF::Inspector::Page.analyze(response.body)
+ expect(page_analysis.pages.size).to be >= 3
+ end
+ end
end
diff --git a/spec/db/seeds_spec.rb b/spec/db/seeds_spec.rb
index bc5b9be1..0f56abac 100644
--- a/spec/db/seeds_spec.rb
+++ b/spec/db/seeds_spec.rb
@@ -1,4 +1,5 @@
require 'rails_helper'
+require 'rake'
describe 'Seeds' do
it 'should seed the database without errors' do
@@ -7,4 +8,11 @@
Rails.application.load_seed
}.to_not raise_error
end
+end
+
+describe 'Sample data' do
+ it 'should load sample data without errors' do
+ Rails.application.load_tasks
+ Rake::Task['db:populate_sample_data'].invoke
+ end
end
\ No newline at end of file
diff --git a/spec/factories/application_letters.rb b/spec/factories/application_letters.rb
index d8476e3b..d7c2c79d 100644
--- a/spec/factories/application_letters.rb
+++ b/spec/factories/application_letters.rb
@@ -25,6 +25,17 @@
event
end
+ factory :application_letter2, parent: :application_letter do
+ grade 11
+ experience "A lot"
+ motivation "Ich bin sehr motiviert, glaubt mir."
+ emergency_number "110"
+ vegeterian true
+ end
+
+ factory :application_letter_long, parent: :application_letter do
+ motivation "Ich bin sehr motiviert, glaubt mir." * 200
+ end
factory :application_letter_deadline_over, parent: :application_letter do
association :event, factory: :event, application_deadline: Date.yesterday
@@ -37,4 +48,8 @@
factory :application_letter_rejected, parent: :application_letter do
status :rejected
end
+
+ factory :application_letter_alternative, parent: :application_letter do
+ status :alternative
+ end
end
diff --git a/spec/features/event_spec.rb b/spec/features/event_spec.rb
index e84af04d..59c69393 100644
--- a/spec/features/event_spec.rb
+++ b/spec/features/event_spec.rb
@@ -97,6 +97,29 @@
expect(page).to have_text("Bewerbungsschluss muss vor Beginn der Veranstaltung liegen")
end
+
+ it "should not display errors on date ranges twice", js: true do
+ visit new_event_path
+
+ fill_in "Maximale Teilnehmerzahl", :with => 25
+
+ within page.find("#event-date-pickers").all("div")[0] do
+ fill_in "event[date_ranges_attributes][][start_date]", with: I18n.l(Date.current.prev_day(7))
+ fill_in "event[date_ranges_attributes][][end_date]", with: I18n.l(Date.yesterday.prev_day(7))
+ end
+
+ click_link "Zeitspanne hinzufügen"
+
+ within page.find("#event-date-pickers").all("div")[1] do
+ fill_in "event[date_ranges_attributes][][start_date]", with: I18n.l(Date.current)
+ fill_in "event[date_ranges_attributes][][end_date]", with: I18n.l(Date.yesterday)
+ end
+
+ click_button I18n.t(".events.form.publish")
+
+ expect(page).to have_css("div.has-error")
+ expect(page).to have_content("kann nicht vor Start-Datum liegen", count: 1)
+ end
end
describe "show page" do
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 6fa394fe..db49213e 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -124,7 +124,7 @@ def mock_writing_to_filesystem
find('input[name=commit]').click
- expect(page).to have_text('Profile was successfully updated.')
+ expect(page).to have_text(I18n.t('profiles.successful_update'))
end
scenario "user fills in an invalid birth date" do
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index 1eb745c5..763ada1e 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -106,6 +106,13 @@
expect(ability).to be_able_to(:view_applicants, Event)
end
+
+ it "can print an event's applications as #{role}" do
+ user = FactoryGirl.create(:user, role: role)
+ ability = Ability.new(user)
+
+ expect(ability).to be_able_to(:print_applications, Event)
+ end
end
it "cannot view and add notes to application letters as pupil" do
@@ -122,6 +129,13 @@
expect(ability).to_not be_able_to(:view_applicants, Event)
end
+ it "cannot print applications for an event as pupil" do
+ user = FactoryGirl.create(:user, role: :pupil)
+ ability = Ability.new(user)
+
+ expect(ability).to_not be_able_to(:print_applications, Event)
+ end
+
it "can do everything as admin" do
user = FactoryGirl.create(:user, role: :admin)
ability = Ability.new(user)
@@ -149,4 +163,41 @@
expect(ability).to_not be_able_to(:update, another_application)
expect(ability).to_not be_able_to(:destroy, another_application)
end
+
+ %i[pupil coach].each do |role|
+ it "cannot update application letter status as #{role}" do
+ user = FactoryGirl.create(:user, role: role)
+ ability = Ability.new(user)
+
+ expect(ability).to_not be_able_to(:update_status, ApplicationLetter)
+ end
+ end
+
+ it "can update application letter status as organizer" do
+ user = FactoryGirl.create(:user, role: :organizer)
+ another_user = FactoryGirl.create(:user)
+ another_application = FactoryGirl.create(:application_letter, user: another_user)
+ ability = Ability.new(user)
+
+ expect(ability).to be_able_to(:update_status, another_application)
+ end
+
+ it "can manage events as organzier" do
+ user = FactoryGirl.create(:user, role: :organizer)
+ ability = Ability.new(user)
+ expect(ability).to be_able_to(:manage, Event)
+ end
+
+ it "can create requests as pupil" do
+ user = FactoryGirl.create(:user, role: :pupil)
+ ability = Ability.new(user)
+ expect(ability).to be_able_to(:create, Request)
+ expect(ability).to be_able_to(:new, Request)
+ end
+
+ it "can manage requests as organzier" do
+ user = FactoryGirl.create(:user, role: :organizer)
+ ability = Ability.new(user)
+ expect(ability).to be_able_to(:manage, Request)
+ end
end
diff --git a/spec/views/application_letters/index.html.erb_spec.rb b/spec/views/application_letters/index.html.erb_spec.rb
new file mode 100644
index 00000000..0e94c102
--- /dev/null
+++ b/spec/views/application_letters/index.html.erb_spec.rb
@@ -0,0 +1,55 @@
+require 'rails_helper'
+
+RSpec.describe "application_letters/index", type: :view do
+
+ context "checks states of applications" do
+ it "checks if page displays accepted application" do
+ @application_letters = [FactoryGirl.create(:application_letter_accepted)]
+ render
+ expect(rendered).to have_content(I18n.t("application_status.accepted"))
+ end
+ it "checks if page displays rejected application" do
+ @application_letters = [FactoryGirl.create(:application_letter_rejected)]
+ render
+ expect(rendered).to have_content(I18n.t("application_status.rejected"))
+ end
+ it "checks if page displays pending application after deadline" do
+ @application_letters = [FactoryGirl.create(:application_letter)]
+ @application_letters[0].event.application_deadline = Date.yesterday
+ render
+ expect(rendered).to have_content(I18n.t("application_status.pending_after_deadline"))
+ end
+ it "checks if page displays pending application before deadline" do
+ @application_letters = [FactoryGirl.create(:application_letter)]
+ render
+ expect(rendered).to have_content(I18n.t("application_status.pending_before_deadline"))
+ end
+ it "checks if page displays alternative status application letter" do
+ @application_letters = [FactoryGirl.create(:application_letter_alternative)]
+ render
+ expect(rendered).to have_content(I18n.t("application_status.alternative"))
+ end
+ end
+
+ it "should display the name of the event" do
+ @application_letters = [FactoryGirl.create(:application_letter)]
+ render
+ expect(rendered).to have_content(@application_letters[0].event.name)
+ end
+
+ it "should display the edit button for a pending event" do
+ @application_letters = [FactoryGirl.create(:application_letter)]
+ render
+ expect(rendered).to have_css("a.btn", :text => "Bearbeiten")
+ end
+ it "should not display edit button after deadline" do
+ @application_letters = [FactoryGirl.build(:application_letter_deadline_over)]
+ render
+ expect(rendered).to_not have_css("a.btn", :text => "Bearbeiten")
+ end
+ it "should have link with the event name" do
+ @application_letters = [FactoryGirl.create(:application_letter)]
+ render
+ expect(rendered).to have_link(@application_letters[0].event.name, href: event_path(@application_letters[0].event.id))
+ end
+end
\ No newline at end of file
diff --git a/spec/views/events/index.html.erb_spec.rb b/spec/views/events/index.html.erb_spec.rb
index 57d0cc55..f9214a35 100644
--- a/spec/views/events/index.html.erb_spec.rb
+++ b/spec/views/events/index.html.erb_spec.rb
@@ -19,4 +19,21 @@
render
expect(rendered).to_not have_text("Id")
end
+
+ it "should not display new, edit, delete buttons for non-organizers" do
+ sign_in(FactoryGirl.create(:user, role: :coach))
+ render
+ expect(rendered).to_not have_link(I18n.t('helpers.links.new'))
+ expect(rendered).to_not have_link(I18n.t('helpers.links.edit'))
+ expect(rendered).to_not have_link(I18n.t('helpers.links.destroy'))
+
+ end
+
+ it "should display new, edit, delete buttons for organizers" do
+ sign_in(FactoryGirl.create(:user, role: :organizer))
+ render
+ expect(rendered).to have_link(I18n.t('helpers.links.new'))
+ expect(rendered).to have_link(I18n.t('helpers.links.edit'))
+ expect(rendered).to have_link(I18n.t('helpers.links.destroy'))
+ end
end
diff --git a/spec/views/events/show.html.erb_spec.rb b/spec/views/events/show.html.erb_spec.rb
index 7bc3cb70..546eabf5 100644
--- a/spec/views/events/show.html.erb_spec.rb
+++ b/spec/views/events/show.html.erb_spec.rb
@@ -53,6 +53,10 @@
expect(rendered).to have_link(t(:details, scope: 'events.applicants_overview'))
end
+ it "displays print applications button" do
+ render
+ expect(rendered).to have_link(t(:print_all, scope: 'events.applicants_overview'))
+ end
it "displays print badges button" do
render
diff --git a/spec/views/requests/index.html.erb_spec.rb b/spec/views/requests/index.html.erb_spec.rb
index 6b9321f9..bf16dd93 100644
--- a/spec/views/requests/index.html.erb_spec.rb
+++ b/spec/views/requests/index.html.erb_spec.rb
@@ -13,4 +13,26 @@
render
assert_select "tr>td", :text => @topics, :count => 2
end
+
+ it "should not display the new button for non-pupils" do
+ render
+ expect(rendered).to_not have_link(I18n.t('helpers.links.new'))
+ end
+
+ it "should display new button but not display edit, delete buttons for non-organizers" do
+ sign_in(FactoryGirl.create(:user, role: :coach))
+ render
+ expect(rendered).to have_link(I18n.t('helpers.links.new'))
+
+ expect(rendered).to_not have_link(I18n.t('helpers.links.edit'))
+ expect(rendered).to_not have_link(I18n.t('helpers.links.destroy'))
+ end
+
+ it "should display edit, delete buttons for organizers" do
+ sign_in(FactoryGirl.create(:user, role: :organizer))
+ render
+
+ expect(rendered).to have_link(I18n.t('helpers.links.edit'))
+ expect(rendered).to have_link(I18n.t('helpers.links.destroy'))
+ end
end
diff --git a/spec/views/requests/show.html.erb_spec.rb b/spec/views/requests/show.html.erb_spec.rb
index b11da680..ccdf7179 100644
--- a/spec/views/requests/show.html.erb_spec.rb
+++ b/spec/views/requests/show.html.erb_spec.rb
@@ -2,11 +2,25 @@
RSpec.describe "requests/show", type: :view do
before(:each) do
- @request = assign(:request, FactoryGirl.create(:request, topics: 'Topics'))
+ @aRequest = assign(:request, FactoryGirl.create(:request, topics: 'Topics'))
end
it "renders attributes" do
render
- expect(rendered).to have_text(@request.topics)
+ expect(rendered).to have_text(@aRequest.topics)
+ end
+
+ it "should not display edit, delete buttons for non-organizers" do
+ sign_in(FactoryGirl.create(:user, role: :coach))
+ render
+ expect(rendered).to_not have_link(I18n.t('helpers.links.edit'))
+ expect(rendered).to_not have_link(I18n.t('helpers.links.destroy'))
+ end
+
+ it "should display edit, delete buttons for organizers" do
+ sign_in(FactoryGirl.create(:user, role: :organizer))
+ render
+ expect(rendered).to have_link(I18n.t('helpers.links.edit'))
+ expect(rendered).to have_link(I18n.t('helpers.links.destroy'))
end
end