Merge branch 'master' into move-ability-namespace
This commit is contained in:
commit
3e396f7070
35 changed files with 404 additions and 70 deletions
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.*
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -36,3 +36,5 @@ pickle-email-*.html
|
||||||
.env.development
|
.env.development
|
||||||
.env.test
|
.env.test
|
||||||
.env.local
|
.env.local
|
||||||
|
docker-compose.env
|
||||||
|
docker-compose.yml
|
||||||
|
|
|
||||||
45
Dockerfile
Normal file
45
Dockerfile
Normal 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"]
|
||||||
3
Gemfile
3
Gemfile
|
|
@ -22,9 +22,6 @@ gem 'responders', '~> 2.0'
|
||||||
gem 'mysql2'
|
gem 'mysql2'
|
||||||
# gem 'pg'
|
# gem 'pg'
|
||||||
|
|
||||||
# for observing records
|
|
||||||
gem 'rails-observers'
|
|
||||||
|
|
||||||
# for tracking data changes
|
# for tracking data changes
|
||||||
gem 'paper_trail'
|
gem 'paper_trail'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -399,8 +399,6 @@ GEM
|
||||||
rails-i18n (4.0.8)
|
rails-i18n (4.0.8)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
railties (~> 4.0)
|
railties (~> 4.0)
|
||||||
rails-observers (0.1.2)
|
|
||||||
activemodel (~> 4.0)
|
|
||||||
rails_12factor (0.0.3)
|
rails_12factor (0.0.3)
|
||||||
rails_serve_static_assets
|
rails_serve_static_assets
|
||||||
rails_stdout_logging
|
rails_stdout_logging
|
||||||
|
|
@ -632,7 +630,6 @@ DEPENDENCIES
|
||||||
rails-assets-trianglify!
|
rails-assets-trianglify!
|
||||||
rails-assets-waypoints!
|
rails-assets-waypoints!
|
||||||
rails-i18n (~> 4.0.0)
|
rails-i18n (~> 4.0.0)
|
||||||
rails-observers
|
|
||||||
rails_12factor
|
rails_12factor
|
||||||
rdoc-generator-fivefish
|
rdoc-generator-fivefish
|
||||||
redcarpet
|
redcarpet
|
||||||
|
|
|
||||||
51
INSTALL.md
51
INSTALL.md
|
|
@ -11,7 +11,9 @@ OSEM is an [semantic versioned](http://semver.org/) app. That means given a vers
|
||||||
## Download
|
## 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))
|
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
|
## 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)
|
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
|
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) ;-)
|
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">
|
<img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy">
|
||||||
</a>
|
</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
|
## Configure
|
||||||
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file.
|
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Comment < ActiveRecord::Base
|
||||||
# want user to vote on the quality of comments.
|
# want user to vote on the quality of comments.
|
||||||
#acts_as_votable
|
#acts_as_votable
|
||||||
|
|
||||||
belongs_to :commentable, polymorphic: true
|
belongs_to :commentable, counter_cache: true, polymorphic: true
|
||||||
|
|
||||||
# NOTE: Comments belong to a user
|
# NOTE: Comments belong to a user
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
|
||||||
11
app/models/concerns/revision_count.rb
Normal file
11
app/models/concerns/revision_count.rb
Normal 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
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
class Conference < ActiveRecord::Base
|
class Conference < ActiveRecord::Base
|
||||||
|
include RevisionCount
|
||||||
require 'uri'
|
require 'uri'
|
||||||
serialize :events_per_week, Hash
|
serialize :events_per_week, Hash
|
||||||
# Needed to call 'Conference.with_role' in /models/ability.rb
|
# Needed to call 'Conference.with_role' in /models/ability.rb
|
||||||
|
|
@ -6,6 +7,8 @@ class Conference < ActiveRecord::Base
|
||||||
resourcify :roles, dependent: :delete_all
|
resourcify :roles, dependent: :delete_all
|
||||||
|
|
||||||
default_scope { order('start_date DESC') }
|
default_scope { order('start_date DESC') }
|
||||||
|
scope :upcoming, (-> { where('end_date >= ?', Date.current) })
|
||||||
|
scope :past, (-> { where('end_date < ?', Date.current) })
|
||||||
|
|
||||||
belongs_to :organization
|
belongs_to :organization
|
||||||
|
|
||||||
|
|
@ -734,6 +737,15 @@ class Conference < ActiveRecord::Base
|
||||||
(start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0
|
(start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return the current conference object to be used in RevisionCount
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +ActiveRecord+
|
||||||
|
def conference
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Returns a different html colour for every i and consecutive colors are
|
# Returns a different html colour for every i and consecutive colors are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
class Event < ActiveRecord::Base
|
class Event < ActiveRecord::Base
|
||||||
include ActiveRecord::Transitions
|
include ActiveRecord::Transitions
|
||||||
|
include RevisionCount
|
||||||
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
|
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
|
||||||
|
|
||||||
acts_as_commentable
|
acts_as_commentable
|
||||||
|
|
@ -251,6 +252,10 @@ class Event < ActiveRecord::Base
|
||||||
event_schedules.find_by(schedule_id: program.selected_schedule_id).try(:start_time)
|
event_schedules.find_by(schedule_id: program.selected_schedule_id).try(:start_time)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def conference
|
||||||
|
program.conference
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,5 @@ class PhysicalTicket < ActiveRecord::Base
|
||||||
has_one :ticket, through: :ticket_purchase
|
has_one :ticket, through: :ticket_purchase
|
||||||
has_one :conference, through: :ticket_purchase
|
has_one :conference, through: :ticket_purchase
|
||||||
has_one :user, through: :ticket_purchase
|
has_one :user, through: :ticket_purchase
|
||||||
|
has_many :ticket_scannings
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
class Room < ActiveRecord::Base
|
class Room < ActiveRecord::Base
|
||||||
|
include RevisionCount
|
||||||
belongs_to :venue
|
belongs_to :venue
|
||||||
has_many :event_schedules, dependent: :destroy
|
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
|
validates :size, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
||||||
|
|
||||||
|
def conference
|
||||||
|
venue.conference
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def generate_guid
|
def generate_guid
|
||||||
|
|
|
||||||
3
app/models/ticket_scanning.rb
Normal file
3
app/models/ticket_scanning.rb
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
class TicketScanning < ActiveRecord::Base
|
||||||
|
belongs_to :physical_ticket
|
||||||
|
end
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
class Track < ActiveRecord::Base
|
class Track < ActiveRecord::Base
|
||||||
|
include RevisionCount
|
||||||
belongs_to :program
|
belongs_to :program
|
||||||
has_many :events, dependent: :nullify
|
has_many :events, dependent: :nullify
|
||||||
|
|
||||||
|
|
@ -16,6 +17,10 @@ class Track < ActiveRecord::Base
|
||||||
|
|
||||||
before_validation :capitalize_color
|
before_validation :capitalize_color
|
||||||
|
|
||||||
|
def conference
|
||||||
|
program.conference
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def generate_guid
|
def generate_guid
|
||||||
|
|
|
||||||
|
|
@ -184,4 +184,4 @@
|
||||||
%ul.dropdown-menu{ role: 'menu' }
|
%ul.dropdown-menu{ role: 'menu' }
|
||||||
= render 'change_state_dropdown', event: event
|
= render 'change_state_dropdown', event: event
|
||||||
%td.text-center
|
%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'
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@
|
||||||
%td
|
%td
|
||||||
= organization.name
|
= organization.name
|
||||||
%td
|
%td
|
||||||
= organization.conferences.count
|
= organization.conferences.upcoming.count
|
||||||
%td
|
%td
|
||||||
= organization.conferences.count
|
= organization.conferences.past.count
|
||||||
%td
|
%td
|
||||||
.btn-group
|
.btn-group
|
||||||
= link_to 'Edit', edit_admin_organization_path(organization),
|
= link_to 'Edit', edit_admin_organization_path(organization),
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
%span.fa.fa-cog
|
%span.fa.fa-cog
|
||||||
Manage
|
Manage
|
||||||
= conference.short_title
|
= conference.short_title
|
||||||
- if (current_user.is_admin) || (current_user.has_role? :organizer, :any)
|
- if can? :new, Conference.new
|
||||||
%li
|
%li
|
||||||
= link_to(new_admin_conference_path) do
|
= link_to(new_admin_conference_path) do
|
||||||
%span.fa.fa-plus
|
%span.fa.fa-plus
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
%span.fa.fa-cog
|
%span.fa.fa-cog
|
||||||
Manage
|
Manage
|
||||||
= conference.short_title
|
= conference.short_title
|
||||||
- if can? :create, Conference
|
- if can? :new, Conference.new
|
||||||
%li
|
%li
|
||||||
= link_to(new_admin_conference_path) do
|
= link_to(new_admin_conference_path) do
|
||||||
%span.fa.fa-plus
|
%span.fa.fa-plus
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@
|
||||||
= link_to(admin_conferences_path()) do
|
= link_to(admin_conferences_path()) do
|
||||||
%span.fa.fa-home
|
%span.fa.fa-home
|
||||||
Administration
|
Administration
|
||||||
- if can? :create, Conference
|
- if can? :new, Conference.new
|
||||||
=link_to(new_admin_conference_path) do
|
=link_to(new_admin_conference_path) do
|
||||||
%span.fa.fa-plus
|
%span.fa.fa-plus
|
||||||
Create Conference
|
New Conference
|
||||||
-if @conference and @conference.id and can? :show, @conference
|
-if @conference and @conference.id and can? :show, @conference
|
||||||
%li
|
%li
|
||||||
= link_to(admin_conference_path(@conference.short_title)) do
|
= link_to(admin_conference_path(@conference.short_title)) do
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ module Osem
|
||||||
|
|
||||||
# Activate observers that should always be running.
|
# Activate observers that should always be running.
|
||||||
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
# 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.
|
# 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.
|
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||||
|
|
|
||||||
7
config/database.yml.docker
Normal file
7
config/database.yml.docker
Normal 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'] %>
|
||||||
10
db/migrate/20161229080315_add_comments_count_to_events.rb
Normal file
10
db/migrate/20161229080315_add_comments_count_to_events.rb
Normal 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
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddDefaultToRevisionInConference < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_column :conferences, :revision, :integer, default: 0, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
9
db/migrate/20170711102511_create_ticket_scannings.rb
Normal file
9
db/migrate/20170711102511_create_ticket_scannings.rb
Normal 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
|
||||||
62
db/schema.rb
62
db/schema.rb
|
|
@ -11,22 +11,19 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20170629162450) do
|
ActiveRecord::Schema.define(version: 20170711102511) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
|
||||||
enable_extension "plpgsql"
|
|
||||||
|
|
||||||
create_table "ahoy_events", force: :cascade do |t|
|
create_table "ahoy_events", force: :cascade do |t|
|
||||||
t.integer "visit_id"
|
t.uuid "visit_id", limit: 16
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.text "properties"
|
t.text "properties"
|
||||||
t.datetime "time"
|
t.datetime "time"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time", 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", using: :btree
|
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", using: :btree
|
add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id"
|
||||||
|
|
||||||
create_table "answers", force: :cascade do |t|
|
create_table "answers", force: :cascade do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
|
|
@ -69,9 +66,9 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.integer "rgt"
|
t.integer "rgt"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_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", using: :btree
|
add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type"
|
||||||
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
|
add_index "comments", ["user_id"], name: "index_comments_on_user_id"
|
||||||
|
|
||||||
create_table "commercials", force: :cascade do |t|
|
create_table "commercials", force: :cascade do |t|
|
||||||
t.string "commercial_id"
|
t.string "commercial_id"
|
||||||
|
|
@ -93,7 +90,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.string "logo_file_name"
|
t.string "logo_file_name"
|
||||||
t.integer "revision"
|
t.integer "revision", default: 0, null: false
|
||||||
t.boolean "use_vpositions", default: false
|
t.boolean "use_vpositions", default: false
|
||||||
t.boolean "use_vdays", default: false
|
t.boolean "use_vdays", default: false
|
||||||
t.boolean "use_volunteers"
|
t.boolean "use_volunteers"
|
||||||
|
|
@ -142,7 +139,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
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|
|
create_table "difficulty_levels", force: :cascade do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
|
|
@ -195,10 +192,10 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
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", "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", using: :btree
|
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", using: :btree
|
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", using: :btree
|
add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id"
|
||||||
|
|
||||||
create_table "event_types", force: :cascade do |t|
|
create_table "event_types", force: :cascade do |t|
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
|
|
@ -242,6 +239,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.boolean "is_highlight", default: false
|
t.boolean "is_highlight", default: false
|
||||||
t.integer "program_id"
|
t.integer "program_id"
|
||||||
t.integer "max_attendees"
|
t.integer "max_attendees"
|
||||||
|
t.integer "comments_count", default: 0, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "events_registrations", force: :cascade do |t|
|
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
|
t.integer "schedule_interval", default: 15, null: false
|
||||||
end
|
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|
|
create_table "qanswers", force: :cascade do |t|
|
||||||
t.integer "question_id"
|
t.integer "question_id"
|
||||||
|
|
@ -384,8 +382,8 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.string "resource_type"
|
t.string "resource_type"
|
||||||
end
|
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", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
|
||||||
add_index "roles", ["name"], name: "index_roles_on_name", using: :btree
|
add_index "roles", ["name"], name: "index_roles_on_name"
|
||||||
|
|
||||||
create_table "rooms", force: :cascade do |t|
|
create_table "rooms", force: :cascade do |t|
|
||||||
t.string "guid", null: false
|
t.string "guid", null: false
|
||||||
|
|
@ -400,7 +398,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
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|
|
create_table "splashpages", force: :cascade do |t|
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
|
|
@ -470,6 +468,12 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.integer "week"
|
t.integer "week"
|
||||||
end
|
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|
|
create_table "tickets", force: :cascade do |t|
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
|
|
@ -524,17 +528,17 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.boolean "is_disabled", default: false
|
t.boolean "is_disabled", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", 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, using: :btree
|
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, using: :btree
|
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, using: :btree
|
add_index "users", ["username"], name: "index_users_on_username", unique: true
|
||||||
|
|
||||||
create_table "users_roles", force: :cascade do |t|
|
create_table "users_roles", force: :cascade do |t|
|
||||||
t.integer "role_id"
|
t.integer "role_id"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
end
|
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|
|
create_table "vchoices", force: :cascade do |t|
|
||||||
t.integer "vday_id"
|
t.integer "vday_id"
|
||||||
|
|
@ -578,10 +582,10 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
end
|
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|
|
create_table "visits", force: :cascade do |t|
|
||||||
t.uuid "visitor_id"
|
t.uuid "visitor_id", limit: 16
|
||||||
t.string "ip"
|
t.string "ip"
|
||||||
t.text "user_agent"
|
t.text "user_agent"
|
||||||
t.text "referrer"
|
t.text "referrer"
|
||||||
|
|
@ -603,7 +607,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do
|
||||||
t.datetime "started_at"
|
t.datetime "started_at"
|
||||||
end
|
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|
|
create_table "votes", force: :cascade do |t|
|
||||||
t.integer "event_id"
|
t.integer "event_id"
|
||||||
|
|
|
||||||
39
docker-compose.env.example
Normal file
39
docker-compose.env.example
Normal 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
|
||||||
29
docker-compose.yml.example
Normal file
29
docker-compose.yml.example
Normal 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
51
docker/init.sh
Normal 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
|
||||||
|
|
@ -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_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('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('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)
|
visit admin_conference_venue_rooms_path(conference.short_title)
|
||||||
expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title))
|
expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title))
|
||||||
|
|
|
||||||
|
|
@ -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('Registrations', href: "/admin/conferences/#{conference.short_title}/registrations")
|
||||||
expect(page).to have_link('Questions', href: "/admin/conferences/#{conference.short_title}/questions")
|
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('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
|
visit admin_organizations_path
|
||||||
expect(current_path).to eq(admin_organizations_path)
|
expect(current_path).to eq(admin_organizations_path)
|
||||||
|
|
|
||||||
|
|
@ -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('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('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('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)
|
visit edit_admin_conference_path(conference.short_title)
|
||||||
expect(current_path).to eq(edit_admin_conference_path(conference.short_title))
|
expect(current_path).to eq(edit_admin_conference_path(conference.short_title))
|
||||||
|
|
|
||||||
|
|
@ -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('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('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('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)
|
visit admin_conference_path(other_conference.short_title)
|
||||||
expect(page).to have_link('Add venue', href: "/admin/conferences/#{other_conference.short_title}/venue/new")
|
expect(page).to have_link('Add venue', href: "/admin/conferences/#{other_conference.short_title}/venue/new")
|
||||||
|
|
|
||||||
|
|
@ -1660,4 +1660,48 @@ describe Conference do
|
||||||
expect{ conference.save }.to change{ EventSchedule.count }.from(2).to(1)
|
expect{ conference.save }.to change{ EventSchedule.count }.from(2).to(1)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,29 @@ describe Event do
|
||||||
end
|
end
|
||||||
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
|
describe 'scope ' do
|
||||||
context 'confirmed' do
|
context 'confirmed' do
|
||||||
it 'returns only confirmed events' do
|
it 'returns only confirmed events' do
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue