Skip to content

Commit

Permalink
Implementing a button for Presence in the 2de kamer (#449)
Browse files Browse the repository at this point in the history
* intial commit

* Remove a mistake from permissions.rb

* added migration file

* Fixed lint
  • Loading branch information
lodewiges authored Nov 11, 2024
1 parent 3e2904b commit fbf1070
Show file tree
Hide file tree
Showing 18 changed files with 265 additions and 4 deletions.
2 changes: 2 additions & 0 deletions app/controllers/v1/study_room_presences_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class V1::StudyRoomPresencesController < V1::ApplicationController
end
20 changes: 20 additions & 0 deletions app/models/study_room_presence.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class StudyRoomPresence < ApplicationRecord
belongs_to :user

validates :start_time, presence: true
validates :end_time, presence: true
validates_datetime :end_time, after: :start_time
validates :status, inclusion: { in: %w[chilling studying banaan] }

scope :current, (lambda {
where('start_time <= :current_time AND end_time >= :current_time',
current_time: Time.current)
})
scope :future, (lambda {
where('start_time >= :current_time', current_time: Time.current)
})
scope :current_and_future, (lambda {
where('(start_time <= :current_time AND end_time >= :current_time)
or (start_time >= :current_time)', current_time: Time.current)
})
end
5 changes: 3 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class User < ApplicationRecord # rubocop:disable Metrics/ClassLength
has_many :user_permissions, through: :permissions_users, source: :permission
has_many :article_comments, foreign_key: :author_id
has_many :board_room_presences, dependent: :delete_all
has_many :study_room_presences, dependent: :delete_all
has_many :photo_comments, foreign_key: :author_id
has_many :created_photo_tags, class_name: 'PhotoTag', foreign_key: :author_id,
dependent: :delete_all
Expand Down Expand Up @@ -214,8 +215,8 @@ def allow_tomato_sharing_valid?
return unless allow_tomato_sharing_changed?(from: true, to: false)

errors.add(:allow_tomato_sharing,
'before being removed from tomato your credits needs to be zero.
Please ask the board to be removed from tomato.')
'before being removed from sofia your credits needs to be zero.
Please ask the board to be removed from sofia.')
end

def generate_ical_secret_key
Expand Down
2 changes: 2 additions & 0 deletions app/policies/study_room_presence_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class StudyRoomPresencePolicy < ApplicationPolicy
end
17 changes: 17 additions & 0 deletions app/resources/v1/study_room_presence_resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class V1::StudyRoomPresenceResource < V1::ApplicationResource
attributes :start_time, :end_time, :status

has_one :user, always_include_linkage_data: true

filter :current, apply: ->(records, _value, _options) { records.current }
filter :future, apply: ->(records, _value, _options) { records.future }
filter :current_and_future, apply: ->(records, _value, _options) { records.current_and_future }

before_create do
@model.user_id = current_user.id
end

def self.creatable_fields(_context)
%i[start_time end_time status]
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
jsonapi_resources :articles
jsonapi_resources :article_comments
jsonapi_resources :board_room_presences
jsonapi_resources :study_room_presences
jsonapi_resources :books do
collection do
get :isbn_lookup
Expand Down
17 changes: 17 additions & 0 deletions db/migrate/20241027103012_create_study_room_presence.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class CreateStudyRoomPresence < ActiveRecord::Migration[7.0]
def change
create_table :study_room_presences do |t|
t.datetime :start_time, null: false
t.datetime :end_time, null: false
t.text :status, null: false
t.integer :user_id, null: false
t.datetime :deleted_at
t.timestamps
end
end

Permission.create(name: 'study_room_presence.create')
Permission.create(name: 'study_room_presence.read')
Permission.create(name: 'study_room_presence.update')
Permission.create(name: 'study_room_presence.destroy')
end
13 changes: 11 additions & 2 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_10_18_155243) do
ActiveRecord::Schema[7.0].define(version: 2024_10_27_103012) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -523,6 +522,16 @@
t.index ["mail_alias_id"], name: "index_stored_mails_on_mail_alias_id"
end

create_table "study_room_presences", force: :cascade do |t|
t.datetime "start_time", null: false
t.datetime "end_time", null: false
t.text "status", null: false
t.integer "user_id", null: false
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "users", id: :serial, force: :cascade do |t|
t.string "email"
t.string "username"
Expand Down
4 changes: 4 additions & 0 deletions db/seeds/content.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# rubocop:disable Style/CombinableLoops
members = Group.find_by(name: 'Leden').users

members.sample(4).each do |user|
FactoryBot.create(:study_room_presence, user:)
end

articles = []
members.sample(15).each do |user|
articles << FactoryBot.create(:article, author: user, group: nil)
Expand Down
3 changes: 3 additions & 0 deletions db/seeds/permissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def create_permissions(permission_map)
'article' => %i[create read update destroy],
'article_comment' => %i[create read update destroy],
'board_room_presence' => %i[create read update destroy],
'study_room_presence' => %i[create read update destroy],
'book' => %i[create read update destroy],
'group' => %i[create read update destroy],
'membership' => %i[create read update destroy],
Expand Down Expand Up @@ -65,6 +66,7 @@ def create_permissions(permission_map)
'article' => %i[create read],
'article_comment' => %i[create read],
'board_room_presence' => %i[read],
'study_room_presence' => %i[create read],
'book' => %i[read],
'group' => %i[read],
'membership' => %i[read],
Expand Down Expand Up @@ -101,6 +103,7 @@ def create_permissions(permission_map)
'article' => %i[read],
'article_comment' => %i[create read],
'board_room_presence' => %i[read],
'study_room_presence' => %i[read],
'book' => [],
'group' => [],
'poll' => [],
Expand Down
11 changes: 11 additions & 0 deletions spec/factories/study_room_presences.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FactoryBot.define do
factory :study_room_presence do
start_time { Faker::Time.between(from: 3.days.ago, to: 5.days.ago) }
end_time { Faker::Time.between(from: 10.days.from_now, to: 5.days.from_now) }
status { %w[chilling studying banaan].sample }
user

trait(:future) { start_time { Faker::Time.between(from: 1.day.from_now, to: 4.days.from_now) } }
trait(:history) { end_time { Faker::Time.between(from: 2.days.ago, to: 1.day.ago) } }
end
end
2 changes: 2 additions & 0 deletions spec/jobs/user_archive_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
describe 'other entities are destroyed' do
before do
create(:board_room_presence, user:)
create(:study_room_presence, user:)
create(:mandate, user:)
create(:transaction, user:)
create(:mail_alias, user:)
Expand All @@ -53,6 +54,7 @@
end

it { expect { job }.to change(BoardRoomPresence, :count).by(-1) }
it { expect { job }.to change(StudyRoomPresence, :count).by(-1) }
it { expect { job }.to change(Debit::Mandate, :count).by(-1) }
it { expect { job }.to change(Debit::Transaction, :count).by(-1) }
it { expect { job }.to change(MailAlias, :count).by(-1) }
Expand Down
112 changes: 112 additions & 0 deletions spec/models/study_room_presence_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
require 'rails_helper'

RSpec.describe StudyRoomPresence, type: :model do
subject(:study_room_presence) { build_stubbed(:study_room_presence) }

describe '#valid?' do
it { expect(study_room_presence).to be_valid }

context 'when without start time' do
subject(:study_room_presence) do
build_stubbed(:study_room_presence, start_time: nil)
end

it { expect(study_room_presence).not_to be_valid }
end

context 'when without end time' do
subject(:study_room_presence) do
build_stubbed(:study_room_presence, end_time: nil)
end

it { expect(study_room_presence).not_to be_valid }
end

context 'when end time before start time' do
subject(:study_room_presence) do
build_stubbed(:study_room_presence,
end_time: 1.day.ago, start_time: 1.day.from_now)
end

it { expect(study_room_presence).not_to be_valid }
end

context 'when without status' do
subject(:study_room_presence) { build_stubbed(:study_room_presence, status: nil) }

it { expect(study_room_presence).not_to be_valid }
end

context 'when without a user' do
subject(:study_room_presence) { build_stubbed(:study_room_presence, user: nil) }

it { expect(study_room_presence).not_to be_valid }
end
end

describe '#current' do
context 'when started in the past and ended in the future' do
before { create(:study_room_presence) }

it { expect(described_class.current.count).to eq 1 }
end

context 'when not yet started' do
before { create(:study_room_presence, start_time: 1.minute.from_now) }

it { expect(described_class.current.count).to eq 0 }
end

context 'when just ended' do
before { create(:study_room_presence, end_time: 1.second.ago) }

it { expect(described_class.current.count).to eq 0 }
end
end

describe '#future' do
context 'when started in the past and ended in the future' do
before { create(:study_room_presence) }

it { expect(described_class.future.count).to eq 0 }
end

context 'when not yet started' do
before { create(:study_room_presence, start_time: 1.minute.from_now) }

it { expect(described_class.future.count).to eq 1 }
end

context 'when just ended' do
before { create(:study_room_presence, end_time: 1.second.ago) }

it { expect(described_class.future.count).to eq 0 }
end
end

describe '#current_and_future' do
context 'when started in the past and ended in the future' do
before { create(:study_room_presence) }

it { expect(described_class.current_and_future.count).to eq 1 }
end

context 'when not yet started' do
before { create(:study_room_presence, start_time: 1.minute.from_now) }

it { expect(described_class.current_and_future.count).to eq 1 }
end

context 'when just ended' do
before { create(:study_room_presence, end_time: 1.second.ago) }

it { expect(described_class.current_and_future.count).to eq 0 }
end

context 'when starting in the future' do
before { create(:study_room_presence, start_time: 1.second.from_now) }

it { expect(described_class.current_and_future.count).to eq 1 }
end
end
end
12 changes: 12 additions & 0 deletions spec/requests/v1/study_room_presence_controller/create_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'rails_helper'

describe V1::StudyRoomPresencesController do
describe 'POST /study_room_presences/:id', version: 1 do
it_behaves_like 'a creatable and permissible model' do
let(:record) { build(:study_room_presence) }
let(:record_url) { '/v1/study_room_presences' }
let(:record_permission) { 'study_room_presence.create' }
let(:invalid_attributes) { { status: '' } }
end
end
end
11 changes: 11 additions & 0 deletions spec/requests/v1/study_room_presence_controller/destroy_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'rails_helper'

describe V1::StudyRoomPresencesController do
describe 'DELETE /study_room_presences/:id', version: 1 do
it_behaves_like 'a destroyable and permissible model' do
let(:record) { create(:study_room_presence) }
let(:record_url) { "/v1/study_room_presences/#{record.id}" }
let(:record_permission) { 'study_room_presence.destroy' }
end
end
end
13 changes: 13 additions & 0 deletions spec/requests/v1/study_room_presence_controller/index_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'rails_helper'

describe V1::StudyRoomPresencesController do
describe 'GET /study_room_presences', version: 1 do
let(:records) { create_list(:study_room_presence, 3) }
let(:record_url) { '/v1/study_room_presences' }
let(:record_permission) { 'study_room_presence.read' }
let(:request) { get(record_url) }

it_behaves_like 'a permissible model'
it_behaves_like 'an indexable model'
end
end
12 changes: 12 additions & 0 deletions spec/requests/v1/study_room_presence_controller/show_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'rails_helper'

describe V1::StudyRoomPresencesController do
describe 'GET /study_room_presences/:id', version: 1 do
it_behaves_like 'a permissible model' do
let(:record) { create(:study_room_presence) }
let(:record_url) { "/v1/study_room_presences/#{record.id}" }
let(:record_permission) { 'study_room_presence.read' }
let(:valid_request) { get(record_url) }
end
end
end
12 changes: 12 additions & 0 deletions spec/requests/v1/study_room_presence_controller/update_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'rails_helper'

describe V1::StudyRoomPresencesController do
describe 'PUT /study_room_presences/:id', version: 1 do
it_behaves_like 'an updatable and permissible model' do
let(:record) { create(:study_room_presence) }
let(:record_url) { "/v1/study_room_presences/#{record.id}" }
let(:record_permission) { 'study_room_presence.update' }
let(:invalid_attributes) { { status: '' } }
end
end
end

0 comments on commit fbf1070

Please sign in to comment.