Merge branch 'master' into move-ability-namespace

This commit is contained in:
Shlok Srivastava 2017-07-13 22:40:44 +05:30 committed by GitHub
commit 3e396f7070
35 changed files with 404 additions and 70 deletions

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
Dockerfile
docker-compose.*

2
.gitignore vendored
View file

@ -36,3 +36,5 @@ pickle-email-*.html
.env.development
.env.test
.env.local
docker-compose.env
docker-compose.yml

45
Dockerfile Normal file
View file

@ -0,0 +1,45 @@
FROM ruby:2.3
MAINTAINER TheAssassin <theassassin@users.noreply.github.com>
# required for compiling assets
RUN apt-get update && \
apt-get install -y nodejs nodejs-legacy mariadb-client imagemagick
# used to run the container without root permissions
RUN adduser --home /osem/ --system --group --disabled-login --disabled-password osem
# required to detect when the database is up and running in init.sh
RUN cd /usr/bin && \
wget https://github.com/jwilder/dockerize/releases/download/v0.3.0/dockerize-linux-amd64-v0.3.0.tar.gz -O dockerize.tar.gz && \
echo "36e8319cdf9d2b07340f456ec61cfa0f495ec6c130b02ad9c116fd55a5c43fa1 dockerize.tar.gz" | sha256sum -c && \
tar -xf dockerize.tar.gz && \
rm dockerize.tar.gz
# explicitly add Gemfile and install dependencies using bundler to make use of
# Docker's caching
WORKDIR /osem/
COPY Gemfile /osem/
COPY Gemfile.lock /osem/
RUN bundle install --without test development
# add OSEM files and prepare them for use inside a Docker container
COPY . /osem/
RUN chown osem.osem /osem/ -R && \
mv /osem/config/database.yml.docker /osem/config/database.yml
# data directory is used to cache the secret key in a file
ENV DATA_DIR /data
RUN install -d -m 0700 -o osem $DATA_DIR
VOLUME ["$DATA_DIR"]
USER osem
EXPOSE 9292
COPY docker/init.sh /init.sh
# a user could override this if they wanted to serve the static files directly
# from a webserver
ENV RAILS_SERVE_STATIC_FILES 1
CMD ["bash", "/init.sh"]

View file

@ -22,9 +22,6 @@ gem 'responders', '~> 2.0'
gem 'mysql2'
# gem 'pg'
# for observing records
gem 'rails-observers'
# for tracking data changes
gem 'paper_trail'

View file

@ -399,8 +399,6 @@ GEM
rails-i18n (4.0.8)
i18n (~> 0.7)
railties (~> 4.0)
rails-observers (0.1.2)
activemodel (~> 4.0)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
@ -632,7 +630,6 @@ DEPENDENCIES
rails-assets-trianglify!
rails-assets-waypoints!
rails-i18n (~> 4.0.0)
rails-observers
rails_12factor
rdoc-generator-fivefish
redcarpet

View file

@ -11,7 +11,9 @@ OSEM is an [semantic versioned](http://semver.org/) app. That means given a vers
## Download
You can find the latest OSEM releases on our [release page](https://github.com/openSUSE/osem/releases/latest) ([older release here](https://github.com/openSUSE/osem/releases))
## Deploy
OSEM is a *Ruby on Rails* application. We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source)
and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various
base operating systems. [Check Google](https://encrypted.google.com/search?hl=en&q=ruby%20on%20rails%20apache%20passenger) ;-)
@ -24,6 +26,55 @@ If you have an heroku account you can also
<img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy">
</a>
### Deploy with Docker
You can deploy OSEM using [Docker](https://docker.com/) and [Docker-Compose](https://docs.docker.com/compose/overview/).
*This is just a short guide and does not explain how to use Docker and/or Docker-Compose. You need some experience with these tools to be able to deploy OSEM with Docker properly.*
First of all, copy `docker-compose.yml.example` to `docker-compose.yml` and `docker-compose.env.example` to `docker-compose.env`. You should immediately change
`docker-compose.env`'s permissions to `0600` to make sure all the passphrases in it are kept secret.
(Tip: the easiest and most secure way to do it is to do it with a single command, for example `install -m 0600 docker-compose.env.example docker-compose.env`).
There are two configurations to deploy OSEM with Docker: *evaluation mode* and *production mode*.
#### Evaluation mode
If you want to evaluate OSEM to see if it fits your needs, the default configuration in `docker-compose.env` will work perfectly fine for you.
For convenience reasons, `docker-compose.yml` already contains a [MailHog](https://github.com/mailhog/MailHog) service configuration. MailHog
is going to catch every email sent by OSEM and displays them on a special web service. Thus, it eliminitates the need to set up an SMTP server just to try out OSEM.
Just point your browser to http://localhost:8025 to get access to registration confirmation links etc.
Run `docker-compose up --build` to start the services. On first run, it will take a few minutes to initialize the database. Thus, wait a few minutes before you open up
http://localhost:9292 in your browser.
#### Production mode
To deploy OSEM for production, you have to make a few changes to `docker-compose.yml`. First, remove (or comment) the `mailhog` service, as it is only useful for evaluation and
cannot be used for production.
You can change the forwarded port from port `9292` to any other value if this port is already in use or you just want to use another one.
Next, you have to modify `docker-compose.env`. This file works as a Docker-like replacement for the regular Rails `.env` files described below.
You can configure any of the configuration values shown in the **Configure** section below in it. The most essential variables are already configured to standard
values in `docker-compose.env` which you most likely want to change.
First, you need to modify the email related settings. You need a working SMTP server for OSEM to send out registration confirmation mails etc.
For security reasons, the following variables have to be changed, too:
- `MYSQL_PASSWORD`
- `MYSQL_ROOT_PASSWORD`
- `SECRET_KEY_BASE`
These variables need to be set to the correct values at first, as they are used to initialize everything. Modification of these variables after installation and initialization is more
complicated and out of this document's scope.
As with any other Docker-Compose configuration, run `docker-compose up --build` (or `docker-compose up --build -d` to run in background) to start the services. During the first
start, the database has to be initialized which can take several minutes. The web service is by default exposed on localhost only as it is intended to be served by a reverse proxy (for SSL
termination, caching etc.).
You should not directly expose the web server port unless you have a good reason to do so.
## Configure
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file.

View file

@ -8,7 +8,7 @@ class Comment < ActiveRecord::Base
# want user to vote on the quality of comments.
#acts_as_votable
belongs_to :commentable, polymorphic: true
belongs_to :commentable, counter_cache: true, polymorphic: true
# NOTE: Comments belong to a user
belongs_to :user

View file

@ -0,0 +1,11 @@
module RevisionCount
extend ActiveSupport::Concern
included do
after_update :increment_revision
end
def increment_revision
conference.update_column(:revision, conference.revision + 1)
end
end

View file

@ -1,4 +1,5 @@
class Conference < ActiveRecord::Base
include RevisionCount
require 'uri'
serialize :events_per_week, Hash
# Needed to call 'Conference.with_role' in /models/ability.rb
@ -6,6 +7,8 @@ class Conference < ActiveRecord::Base
resourcify :roles, dependent: :delete_all
default_scope { order('start_date DESC') }
scope :upcoming, (-> { where('end_date >= ?', Date.current) })
scope :past, (-> { where('end_date < ?', Date.current) })
belongs_to :organization
@ -734,6 +737,15 @@ class Conference < ActiveRecord::Base
(start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0
end
##
# Return the current conference object to be used in RevisionCount
#
# ====Returns
# * +ActiveRecord+
def conference
self
end
private
# Returns a different html colour for every i and consecutive colors are

View file

@ -1,5 +1,6 @@
class Event < ActiveRecord::Base
include ActiveRecord::Transitions
include RevisionCount
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
acts_as_commentable
@ -251,6 +252,10 @@ class Event < ActiveRecord::Base
event_schedules.find_by(schedule_id: program.selected_schedule_id).try(:start_time)
end
def conference
program.conference
end
private
##

View file

@ -3,4 +3,5 @@ class PhysicalTicket < ActiveRecord::Base
has_one :ticket, through: :ticket_purchase
has_one :conference, through: :ticket_purchase
has_one :user, through: :ticket_purchase
has_many :ticket_scannings
end

View file

@ -1,26 +0,0 @@
#
# suseconferenceclient relies on a 'revision' attribute for caching and
# doing some calculations.
#
# It should be incremented after any change in the conference or in any
# associated models
#
# This observer updates the revision column in a non-intrusive way,
# preventing validations, callbacks or exceptions to be triggered
#
# Relying on paper_trail could also be an option, but a 'revision' column
# in table 'conferences' looks like a more simple and straightforward solution
#
class RevisionObserver < ActiveRecord::Observer
observe :conference, :event, :room, :track
def after_save(model)
begin
conference = model.kind_of?(Conference) ? model : model.conference
conference.reload.increment(:revision)
conference.update_column(:revision, conference.revision)
rescue
nil
end
end
end

View file

@ -1,4 +1,5 @@
class Room < ActiveRecord::Base
include RevisionCount
belongs_to :venue
has_many :event_schedules, dependent: :destroy
@ -10,6 +11,10 @@ class Room < ActiveRecord::Base
validates :size, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
def conference
venue.conference
end
private
def generate_guid

View file

@ -0,0 +1,3 @@
class TicketScanning < ActiveRecord::Base
belongs_to :physical_ticket
end

View file

@ -1,4 +1,5 @@
class Track < ActiveRecord::Base
include RevisionCount
belongs_to :program
has_many :events, dependent: :nullify
@ -16,6 +17,10 @@ class Track < ActiveRecord::Base
before_validation :capitalize_color
def conference
program.conference
end
private
def generate_guid

View file

@ -184,4 +184,4 @@
%ul.dropdown-menu{ role: 'menu' }
= render 'change_state_dropdown', event: event
%td.text-center
= link_to "#{event.comment_threads.count}", admin_conference_program_event_path(@conference.short_title, event), anchor: 'comments-div'
= link_to "#{event.comments_count}", admin_conference_program_event_path(@conference.short_title, event), anchor: 'comments-div'

View file

@ -20,9 +20,9 @@
%td
= organization.name
%td
= organization.conferences.count
= organization.conferences.upcoming.count
%td
= organization.conferences.count
= organization.conferences.past.count
%td
.btn-group
= link_to 'Edit', edit_admin_organization_path(organization),

View file

@ -16,7 +16,7 @@
%span.fa.fa-cog
Manage
= conference.short_title
- if (current_user.is_admin) || (current_user.has_role? :organizer, :any)
- if can? :new, Conference.new
%li
= link_to(new_admin_conference_path) do
%span.fa.fa-plus

View file

@ -16,7 +16,7 @@
%span.fa.fa-cog
Manage
= conference.short_title
- if can? :create, Conference
- if can? :new, Conference.new
%li
= link_to(new_admin_conference_path) do
%span.fa.fa-plus

View file

@ -28,10 +28,10 @@
= link_to(admin_conferences_path()) do
%span.fa.fa-home
Administration
- if can? :create, Conference
- if can? :new, Conference.new
=link_to(new_admin_conference_path) do
%span.fa.fa-plus
Create Conference
New Conference
-if @conference and @conference.id and can? :show, @conference
%li
= link_to(admin_conference_path(@conference.short_title)) do

View file

@ -25,7 +25,6 @@ module Osem
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
config.active_record.observers = :revision_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.

View file

@ -0,0 +1,7 @@
production:
adapter: mysql2
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
username: <%= ENV['MYSQL_USER'] %>
password: <%= ENV['MYSQL_PASSWORD'] %>
database: <%= ENV['MYSQL_DATABASE'] %>

View file

@ -0,0 +1,10 @@
class AddCommentsCountToEvents < ActiveRecord::Migration
def change
add_column :events, :comments_count, :integer, default: 0, null: false
Event.find_each do |event|
comments_count = event.comment_threads.count
event.update_attribute(:comments_count, comments_count) unless comments_count.zero?
end
end
end

View file

@ -0,0 +1,5 @@
class AddDefaultToRevisionInConference < ActiveRecord::Migration
def change
change_column :conferences, :revision, :integer, default: 0, null: false
end
end

View file

@ -0,0 +1,9 @@
class CreateTicketScannings < ActiveRecord::Migration
def change
create_table :ticket_scannings do |t|
t.integer :physical_ticket_id, null: false
t.timestamps null: false
end
end
end

View file

@ -11,22 +11,19 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170629162450) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
ActiveRecord::Schema.define(version: 20170711102511) do
create_table "ahoy_events", force: :cascade do |t|
t.integer "visit_id"
t.uuid "visit_id", limit: 16
t.integer "user_id"
t.string "name"
t.text "properties"
t.datetime "time"
end
add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time", using: :btree
add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id", using: :btree
add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree
add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time"
add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id"
add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id"
create_table "answers", force: :cascade do |t|
t.string "title"
@ -69,9 +66,9 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.integer "rgt"
end
add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id", using: :btree
add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type", using: :btree
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id"
add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type"
add_index "comments", ["user_id"], name: "index_comments_on_user_id"
create_table "commercials", force: :cascade do |t|
t.string "commercial_id"
@ -93,7 +90,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.datetime "created_at"
t.datetime "updated_at"
t.string "logo_file_name"
t.integer "revision"
t.integer "revision", default: 0, null: false
t.boolean "use_vpositions", default: false
t.boolean "use_vdays", default: false
t.boolean "use_volunteers"
@ -142,7 +139,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.datetime "updated_at"
end
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority"
create_table "difficulty_levels", force: :cascade do |t|
t.string "title"
@ -195,10 +192,10 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.datetime "updated_at", null: false
end
add_index "event_schedules", ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true, using: :btree
add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id", using: :btree
add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id", using: :btree
add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id", using: :btree
add_index "event_schedules", ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true
add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id"
add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id"
add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id"
create_table "event_types", force: :cascade do |t|
t.string "title", null: false
@ -242,6 +239,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.boolean "is_highlight", default: false
t.integer "program_id"
t.integer "max_attendees"
t.integer "comments_count", default: 0, null: false
end
create_table "events_registrations", force: :cascade do |t|
@ -312,7 +310,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.integer "schedule_interval", default: 15, null: false
end
add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id", using: :btree
add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id"
create_table "qanswers", force: :cascade do |t|
t.integer "question_id"
@ -384,8 +382,8 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.string "resource_type"
end
add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id", using: :btree
add_index "roles", ["name"], name: "index_roles_on_name", using: :btree
add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
add_index "roles", ["name"], name: "index_roles_on_name"
create_table "rooms", force: :cascade do |t|
t.string "guid", null: false
@ -400,7 +398,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.datetime "updated_at", null: false
end
add_index "schedules", ["program_id"], name: "index_schedules_on_program_id", using: :btree
add_index "schedules", ["program_id"], name: "index_schedules_on_program_id"
create_table "splashpages", force: :cascade do |t|
t.integer "conference_id"
@ -470,6 +468,12 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.integer "week"
end
create_table "ticket_scannings", force: :cascade do |t|
t.integer "physical_ticket_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "tickets", force: :cascade do |t|
t.integer "conference_id"
t.string "title", null: false
@ -524,17 +528,17 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.boolean "is_disabled", default: false
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_index "users", ["username"], name: "index_users_on_username", unique: true, using: :btree
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
add_index "users", ["username"], name: "index_users_on_username", unique: true
create_table "users_roles", force: :cascade do |t|
t.integer "role_id"
t.integer "user_id"
end
add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id", using: :btree
add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id"
create_table "vchoices", force: :cascade do |t|
t.integer "vday_id"
@ -578,10 +582,10 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.integer "conference_id"
end
add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree
add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
create_table "visits", force: :cascade do |t|
t.uuid "visitor_id"
t.uuid "visitor_id", limit: 16
t.string "ip"
t.text "user_agent"
t.text "referrer"
@ -603,7 +607,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
t.datetime "started_at"
end
add_index "visits", ["user_id"], name: "index_visits_on_user_id", using: :btree
add_index "visits", ["user_id"], name: "index_visits_on_user_id"
create_table "votes", force: :cascade do |t|
t.integer "event_id"

View file

@ -0,0 +1,39 @@
## database related variables ##
# variables prefixed with MYSQL_ are used by both database and web containers
# variables prefixed with DATABASE_ are used exlusively by the web container
MYSQL_DATABASE=osem
MYSQL_USER=osem
MYSQL_PASSWORD=changemeimmediately
MYSQL_ROOT_PASSWORD=changemeevenmoreimmediately
# the following settings should not be modified unless the database service
# is renamed in docker-compose.yml or you plan to use an external database
DATABASE_HOST=database
DATABASE_PORT=3306
## OSEM options ##
# you can configure any option described in this document here instead of
# having to create a .env file:
# https://github.com/openSUSE/osem/blob/master/dotenv.example
OSEM_NAME=Dockerized OSEM
OSEM_HOSTNAME=http://localhost:9292
OSEM_ERRBIT_HOST=localhost
SECRET_KEY_BASE=changemechangemechangeme
# these settings work for the MailHog server that is enabled by default in
# docker-compose.yml
# if you do not plan to use MailHog (you most likely don't want to), you need
# to change these settings to use an external working mailserver, otherwise
# your users are going to see the HTTP status 500 page
# you should comment out or remove the mailhog service from docker-compose.yml,
# too
OSEM_EMAIL_ADDRESS=osem@mailhog
OSEM_SMTP_AUTHENTICATION=login
OSEM_SMTP_ADDRESS=mailhog
OSEM_SMTP_PORT=1025
OSEM_SMTP_USERNAME=mailhog
OSEM_SMTP_PASSWORD=mailhog

View file

@ -0,0 +1,29 @@
version: "2"
services:
database:
image: mariadb:10.1
env_file: docker-compose.env
volumes:
- database:/var/lib/mysql
mailhog:
image: mailhog/mailhog:latest
ports:
- "127.0.0.1:8025:8025"
web:
build: .
env_file: docker-compose.env
depends_on:
- database
- mailhog
ports:
- "127.0.0.1:9292:9292"
volumes:
- "web:/data"
# these named volumes are used to persist data
volumes:
database:
web:

51
docker/init.sh Normal file
View file

@ -0,0 +1,51 @@
#! /bin/bash
set -e
# data directory is required for caching the secret key in a file
if [ "$DATA_DIR" == "" ]; then
echo -n "Error: DATA_DIR environment variable not set!"
echo "Are you sure you are running this script in a Docker container?"
exit 1
fi
SECRET_KEY_FILE="$DATA_DIR/secret_key"
if [ ! -f "$SECRET_KEY_FILE" ]; then
echo ">>> Creating a new secret key file..."
install -m 0600 /dev/null "$SECRET_KEY_FILE"
SECRET_KEY=$(bundle exec rake secret)
echo "$key" > "$SECRET_KEY_FILE"
chmod -w "$SECRET_KEY_FILE"
else
SECRET_KEY=$(cat "$SECRET_KEY_FILE")
fi
export SECRET_KEY
export RAILS_ENV=production
install -m 0600 /dev/null .my.cnf
cat > .my.cnf <<ABC
[client]
user=$MYSQL_USER
password=$MYSQL_PASSWORD
ABC
echo ">>> Waiting for database to get ready to connect..."
dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s true
if [ $(echo "show tables;" | mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then
echo ">>> Initializing database..."
bundle exec rake db:schema:load
fi
echo ">>> Upgrading database..."
bundle exec rake db:migrate
rm .my.cnf
echo ">>> Precompiling assets..."
bundle exec rake assets:precompile
echo ">>> Starting application server..."
exec bundle exec rails server -e production -b 0.0.0.0 -p 9292

View file

@ -46,6 +46,7 @@ feature 'Has correct abilities' do
expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference.short_title}/targets")
expect(page).to have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles")
expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources")
expect(page).to_not have_link('New Conference', href: '/admin/conferences/new')
visit admin_conference_venue_rooms_path(conference.short_title)
expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title))

View file

@ -46,6 +46,7 @@ feature 'Has correct abilities' do
expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference.short_title}/registrations")
expect(page).to have_link('Questions', href: "/admin/conferences/#{conference.short_title}/questions")
expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference.short_title}/emails")
expect(page).to_not have_link('New Conference', href: '/admin/conferences/new')
visit admin_organizations_path
expect(current_path).to eq(admin_organizations_path)

View file

@ -55,6 +55,7 @@ feature 'Has correct abilities' do
expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference.short_title}/emails")
expect(page).to have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles")
expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources")
expect(page).to have_link('New Conference', href: '/admin/conferences/new')
visit edit_admin_conference_path(conference.short_title)
expect(current_path).to eq(edit_admin_conference_path(conference.short_title))

View file

@ -58,6 +58,7 @@ feature 'Has correct abilities' do
expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference.short_title}/emails")
expect(page).to have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles")
expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources")
expect(page).to_not have_link('New Conference', href: '/admin/conferences/new')
visit admin_conference_path(other_conference.short_title)
expect(page).to have_link('Add venue', href: "/admin/conferences/#{other_conference.short_title}/venue/new")

View file

@ -1660,4 +1660,48 @@ describe Conference do
expect{ conference.save }.to change{ EventSchedule.count }.from(2).to(1)
end
end
describe '#revision' do
let(:track) { create(:track, program: subject.program) }
let(:event) { create(:event, program: subject.program, track: track) }
let(:venue) { create(:venue, conference: subject) }
let(:room) { create(:room, venue: venue) }
it 'for change in conference' do
subject.title = 'changed'
expect{ subject.save }.to change { subject.revision }.by(1)
end
it 'for change in event' do
event.title = 'changed'
expect{ event.save }.to change { subject.revision }.by(1)
end
it 'for change in track' do
track.name = 'changed'
expect{ track.save }.to change { subject.revision }.by(1)
end
it 'for change in room' do
room.name = 'changed'
expect{ room.save }.to change { subject.revision }.by(1)
end
end
describe '.upcoming' do
let!(:upcoming_conference) { create(:conference) }
let!(:past_conference) { create(:conference, start_date: Date.current - 1.days, end_date: Date.current - 1.days) }
subject { Conference.upcoming }
it { is_expected.to eq [upcoming_conference] }
end
describe '.past' do
let!(:upcoming_conference) { create(:conference) }
let!(:past_conference1) { create(:conference, start_date: Date.current - 1.days, end_date: Date.current - 1.days) }
let!(:past_conference2) { create(:conference, start_date: Date.current - 2.days, end_date: Date.current - 1.days) }
subject { Conference.past }
it { is_expected.to eq [past_conference1, past_conference2] }
end
end

View file

@ -98,6 +98,29 @@ describe Event do
end
end
describe '#comments_count' do
context 'has a valid counter cache' do
before do
create(:comment, commentable: event)
end
it 'successfully increments comments_count' do
expected = expect do
create(:comment, commentable: event)
end
expected.to change { event.comments_count }.by(1)
end
it 'successfully decrements comments_count' do
expected = expect do
event.comment_threads.last.destroy
event.reload
end
expected.to change { event.comments_count }.by(-1)
end
end
end
describe 'scope ' do
context 'confirmed' do
it 'returns only confirmed events' do