Skip to content

Commit

Permalink
Merge branch 'dev' into 276_not_public_material_area
Browse files Browse the repository at this point in the history
  • Loading branch information
Niklas Kiefer committed Jan 12, 2017
2 parents 4893a09 + 4756b49 commit 0217c71
Show file tree
Hide file tree
Showing 24 changed files with 280 additions and 67 deletions.
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -4,16 +4,16 @@ A Ruby on Rails app to manage workshops

Branch | Travis CI | Code Analysis | Heroku Deploy | Errbit
------ | ---------- | ------------- | ------------- | ------
master | [![Build Status](https://travis-ci.org/hpi-swt2/workshop-portal.svg?branch=master)](https://travis-ci.org/hpi-swt2/workshop-portal) | [![Coverage Status](https://coveralls.io/repos/github/hpi-swt2/workshop-portal/badge.svg?branch=master)](https://coveralls.io/github/hpi-swt2/workshop-portal?branch=master) [![Code Climate](https://codeclimate.com/github/hpi-swt2/workshop-portal/badges/gpa.svg)](https://codeclimate.com/github/hpi-swt2/workshop-portal/issues) | [![Heroku](https://heroku-badge.herokuapp.com/?app=workshop-portal)](http://workshop-portal.herokuapp.com/) [[link]](http://workshop-portal.herokuapp.com/) | [[link]](http://swt2-errbit-2016.herokuapp.com/) |
production | [![Build Status](https://travis-ci.org/hpi-swt2/workshop-portal.svg?branch=production)](https://travis-ci.org/hpi-swt2/workshop-portal) | [![Coverage Status](https://coveralls.io/repos/github/hpi-swt2/workshop-portal/badge.svg?branch=production)](https://coveralls.io/github/hpi-swt2/workshop-portal?branch=production) [![Code Climate](https://codeclimate.com/github/hpi-swt2/workshop-portal/badges/gpa.svg)](https://codeclimate.com/github/hpi-swt2/workshop-portal/issues) | [![Heroku](https://heroku-badge.herokuapp.com/?app=workshop-portal)](http://workshop-portal.herokuapp.com/) [[link]](http://workshop-portal.herokuapp.com/) | [[link]](http://swt2-errbit-2016.herokuapp.com/) |
dev | [![Build Status](https://travis-ci.org/hpi-swt2/workshop-portal.svg?branch=dev)](https://travis-ci.org/hpi-swt2/workshop-portal) | [![Coverage Status](https://coveralls.io/repos/github/hpi-swt2/workshop-portal/badge.svg?branch=dev)](https://coveralls.io/github/hpi-swt2/workshop-portal?branch=dev) | [![Heroku](https://heroku-badge.herokuapp.com/?app=workshop-portal-dev)](http://workshop-portal-dev.herokuapp.com/) [[link]](http://workshop-portal-dev.herokuapp.com/) |

When all tests succeed on Travis CI, the application is deployed to Heroku. Click the badges for detailed info. <br>
The uptime of the deployed applications can be tracked [here](https://stats.uptimerobot.com/pg2gDuQZQ). <br>
Errors that occur while using the deployed master branch on Heroku are logged to the [Errbit](http://swt2-errbit-2016.herokuapp.com/) error catcher, you can sign in with your Github account.
Errors that occur while using the deployed production branch on Heroku are logged to the [Errbit](http://swt2-errbit-2016.herokuapp.com/) error catcher, you can sign in with your Github account.

## Local Setup

* `bundle install` Install the required Ruby gem dependencies defined in the [Gemfile](https://github.com/hpi-swt2/workshop-portal/blob/master/Gemfile)
* `bundle install` Install the required Ruby gem dependencies defined in the [Gemfile](https://github.com/hpi-swt2/workshop-portal/blob/production/Gemfile)
* `cp database.sqlite.yml database.yml` Select database config (for development we recommend SQLite)
* `rake db:create db:migrate db:seed` Setup database, run migrations, seed the database with defaults
* `rails s` Start the Rails development server (By default runs on _localhost:3000_)
Expand Down
49 changes: 49 additions & 0 deletions app/assets/images/loader.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions app/assets/javascripts/loader.js
@@ -0,0 +1,6 @@
document.addEventListener('turbolinks:visit', function() {
$('.loader').fadeIn();
});
document.addEventListener('turbolinks:load', function() {
$('.loader').fadeOut();
});
22 changes: 22 additions & 0 deletions app/assets/stylesheets/loader.css
@@ -0,0 +1,22 @@

.loader {
position: fixed;
width: 30px;
height: 30px;
bottom: 15px;
right: 15px;
animation: turn 2000ms linear infinite;
-webkit-animation: turn 2000ms linear infinite;
-moz-animation: turn 2000ms linear infinite;
-ms-animation: turn 2000ms linear infinite;
}

@keyframes turn {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@-webkit-keyframes turn {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

1 change: 1 addition & 0 deletions app/controllers/requests_controller.rb
Expand Up @@ -3,6 +3,7 @@ class RequestsController < ApplicationController

# GET /requests
def index
authorize! :index, Request
@requests = Request.all
end

Expand Down
5 changes: 4 additions & 1 deletion app/helpers/applicants_overview_helper.rb
@@ -1,8 +1,11 @@
module ApplicantsOverviewHelper
def sort_caret(label, attr)
is_sorted_ascending = (params[:sort] == attr.to_s) && params[:order] != 'descending'
url = "?sort=#{attr.to_s}" +
"#{'&order=descending' if is_sorted_ascending}" +
"#{'&' + params[:filter].map { |k,v| "filter[#{k}]=#{v}" }.join('&') if params[:filter]}"

"<a class=\"#{'dropup' if is_sorted_ascending}\" href=\"?sort=#{attr.to_s}#{'&order=descending' if is_sorted_ascending}\">
"<a class=\"#{'dropup' if is_sorted_ascending}\" href=\"#{url}\">
#{label} <span class=\"caret\"></span>
</a>".html_safe
end
Expand Down
11 changes: 10 additions & 1 deletion app/helpers/application_helper.rb
Expand Up @@ -16,7 +16,16 @@ def link(link, title, content)
module ApplicationHelper
def menu_items
(menu_item t(:events, scope: 'navbar'), events_path) +
(menu_item t(:requests, scope: 'navbar'), requests_path)
request_menu_item
end

def request_menu_item
if can? :index, Request
item = (menu_item t(:requests, scope: 'navbar'), requests_path)
else
item = (menu_item t(:new_request, scope: 'navbar'), new_request_path)
end
item
end

# Render the given string as markdown
Expand Down
2 changes: 2 additions & 0 deletions app/models/ability.rb
Expand Up @@ -48,6 +48,8 @@ def initialize(user)
# Coaches can view Applications and participants for and view and upload materials for Event
can [:view_applicants, :view_participants, :view_material, :upload_material, :print_applications], Event
can [:view_and_add_notes, :show], ApplicationLetter
can [:print_applications], Event
can :manage, Request
cannot [:check], ApplicationLetter
end
if user.role? :organizer
Expand Down
4 changes: 4 additions & 0 deletions app/models/request.rb
Expand Up @@ -13,4 +13,8 @@ class Request < ActiveRecord::Base
validates_format_of :email, :with => Devise::email_regexp

enum form_of_address: [:mr, :mrs, :prefer_to_omit]

def name
"#{first_name} #{last_name}"
end
end
Expand Up @@ -7,5 +7,7 @@
<% end %>
<br>
<% end %>
<%= hidden_field_tag 'sort', params[:sort] if params[:sort] %>
<%= hidden_field_tag 'order', params[:order] if params[:order] %>
<input class="btn btn-default btn-sm" type="submit" value="<%= t 'events.applicants_overview.filter' %>">
</form>
2 changes: 2 additions & 0 deletions app/views/layouts/application.html.erb
Expand Up @@ -51,5 +51,7 @@
</footer>
</main>

<%= image_tag "loader.svg", class: "loader" %>

</body>
</html>
17 changes: 8 additions & 9 deletions app/views/requests/index.html.erb
Expand Up @@ -5,21 +5,20 @@
<table class="table table-striped">
<thead>
<tr>
<th><%= model_class.human_attribute_name(:id) %></th>
<th><%= model_class.human_attribute_name(:first_name) %></th>
<th><%= model_class.human_attribute_name(:last_name) %></th>
<th><%= model_class.human_attribute_name(:created_at) %></th>
<th><%= model_class.human_attribute_name(:topic_of_workshop) %></th>
<th><%= model_class.human_attribute_name(:name) %></th>
<th><%= model_class.human_attribute_name(:time_period) %></th>
<th><%= model_class.human_attribute_name(:number_of_participants) %></th>
<th><%=t '.actions', :default => t("helpers.actions") %></th>
</tr>
</thead>
<tbody>
<% @requests.each do |request| %>
<tr>
<td><%= link_to request.id, request_path(request) %></td>
<td><%= request.first_name %></td>
<td><%= request.last_name %></td>
<td><%= request.topic_of_workshop %></td>
<td><%=l request.created_at %></td>
<td><%= link_to request.topic_of_workshop, request_path(request) %></td>
<td><%= request.name %></td>
<td><%= request.time_period %></td>
<td><%= request.number_of_participants %></td>
<td>
<% if can? :edit, request %>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
Expand Down
1 change: 1 addition & 0 deletions config/locales/de.yml
Expand Up @@ -32,6 +32,7 @@ de:
my_application_letters: "Meine Bewerbungen"
user_management: "Benutzerverwaltung"
requests: "Anfragen"
new_request: "Anfrage stellen"
profile: "Mein Profil"
create_profile: "Mein Profil anlegen"
settings: "Einstellungen"
Expand Down
3 changes: 2 additions & 1 deletion db/sample_data.rb
Expand Up @@ -23,8 +23,9 @@ def add_sample_data
users[:tobi] = user_tobi
users[:lisa] = user_lisa
users[:max] = user_max
users[:organizer] = user_organizer
users[:coach] = user_coach
users[:organizer] = user_organizer
users[:hpi_admin] = user_admin

profiles = Hash.new
profiles[:pupil] = profile_pupil(users[:pupil])
Expand Down
20 changes: 14 additions & 6 deletions db/sample_data/users.rb
Expand Up @@ -50,18 +50,26 @@ def user_tobi
)
end

def user_coach
User.new(
email: "coach@hpi.de",
password: user_password,
role: :coach
)
end

def user_organizer
User.new(
email: "organizer@workshops.hpi.de",
email: "organizer@hpi.de",
password: user_password,
role: :admin
role: :organizer
)
end

def user_coach
def user_admin
User.new(
email: "coach@workshops.hpi.de",
email: "admin@hpi.de",
password: user_password,
role: :coach
role: :admin
)
end
end
7 changes: 4 additions & 3 deletions db/schema.rb
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20170104135212) do
ActiveRecord::Schema.define(version: 20170108122417) do

create_table "agreement_letters", force: :cascade do |t|
t.integer "user_id", null: false
Expand Down Expand Up @@ -97,8 +97,8 @@
add_index "profiles", ["user_id"], name: "index_profiles_on_user_id"

create_table "requests", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "form_of_address"
t.string "first_name"
t.string "last_name"
Expand All @@ -110,6 +110,7 @@
t.integer "number_of_participants"
t.string "knowledge_level"
t.text "annotations"
t.integer "status", default: 0
end

create_table "users", force: :cascade do |t|
Expand Down
4 changes: 2 additions & 2 deletions spec/controllers/requests_controller_spec.rb
Expand Up @@ -36,9 +36,9 @@
end

describe "GET #index" do
it "assigns all requests as @requests" do
it "disallows viewing all requests per default" do
get :index, session: valid_session
expect(assigns(:requests)).to eq([@a_request])
expect(response).to redirect_to(root_url)
end
end

Expand Down
13 changes: 12 additions & 1 deletion spec/features/events_spec.rb
Expand Up @@ -253,7 +253,7 @@
expect(page).to contain_ordered(names.reverse)
end

scenario "logged in as Organizer I can filter displayed application letters by their status", js: true do
scenario "logged in as Organizer I can filter displayed application letters by their status and simultaneously sort them", js: true do
login(:organizer)
@event = FactoryGirl.create(:event_with_accepted_applications)
@event.application_letters.each do |letter|
Expand All @@ -271,6 +271,17 @@
expect(page).to have_every_text(accepted_names)
expect(page).to have_no_text(not_accepted_names)

# sort this list by name
click_link I18n.t('activerecord.attributes.profile.name')

sorted_accepted_names = @event.application_letters
.to_a
.sort_by { |letter| letter.applicant_age_when_event_starts }
.select { |letter| letter.status.to_sym == :accepted }
.map {|l| l.user.profile.name }
expect(page).to contain_ordered(sorted_accepted_names)

# list rejected, pending
click_button I18n.t 'events.applicants_overview.filter_by'
uncheck I18n.t 'application_status.accepted'
check I18n.t 'application_status.rejected'
Expand Down
48 changes: 42 additions & 6 deletions spec/features/request_spec.rb
@@ -1,6 +1,10 @@
require "rails_helper"

describe "Event", type: :feature do
describe "workshop requests", type: :feature do
before(:each) do
@request = FactoryGirl.create :request
end

describe "create page" do

def fill_in_required_fields
Expand All @@ -14,12 +18,44 @@ def fill_in_required_fields

['Herr', 'Frau', 'Nicht angeben'].each do |form_of_address|
it "should allow picking #{form_of_address} kind form of address" do
visit new_request_path
choose(form_of_address)
fill_in_required_fields
click_button I18n.t('.requests.form.create_request')
expect(page).to have_current_path(request_path(Request.first))
visit new_request_path
choose(form_of_address)
fill_in_required_fields
click_button I18n.t('.requests.form.create_request')
expect(page).to have_current_path(request_path(Request.last))
end
end
end


context "as a user who's not an organizer or coach" do
it "shouldn't display the index page and show an error" do
visit requests_path
expect(page).not_to have_text(@request.topic_of_workshop)
expect(page).to have_text(I18n.t('unauthorized.manage.all'))

profile = FactoryGirl.create(:profile)
pupil = FactoryGirl.create(:user, role: :pupil, profile: profile)
login_as(pupil, scope: :user)

visit requests_path
expect(page).not_to have_text(@request.topic_of_workshop)
expect(page).to have_text(I18n.t('unauthorized.manage.all'))
end
end

context "as a coach or organizer" do
it "should show the index page" do
profile = FactoryGirl.create(:profile)
coach = FactoryGirl.create(:user, role: :coach, profile: profile)
login_as(coach, scope: :user)
visit requests_path
expect(page).to have_text(@request.topic_of_workshop)

organizer = FactoryGirl.create(:user, role: :organizer, profile: profile)
login_as(organizer, scope: :user)
visit requests_path
expect(page).to have_text(@request.topic_of_workshop)
end
end
end

0 comments on commit 0217c71

Please sign in to comment.