diff --git a/Gemfile b/Gemfile index e0c8729..bbd4026 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '3.3.5' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 7.2.1.1' +gem 'rails', '~> 7.2.2.1' # Use Puma as the app server gem 'puma', '~> 6.4' # A PostgreSQL client library for Ruby diff --git a/Gemfile.lock b/Gemfile.lock index 34f24bf..3ff9d3c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,29 +1,29 @@ GEM remote: https://rubygems.org/ specs: - actioncable (7.2.1.2) - actionpack (= 7.2.1.2) - activesupport (= 7.2.1.2) + actioncable (7.2.2.1) + actionpack (= 7.2.2.1) + activesupport (= 7.2.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.1.2) - actionpack (= 7.2.1.2) - activejob (= 7.2.1.2) - activerecord (= 7.2.1.2) - activestorage (= 7.2.1.2) - activesupport (= 7.2.1.2) + actionmailbox (7.2.2.1) + actionpack (= 7.2.2.1) + activejob (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) mail (>= 2.8.0) - actionmailer (7.2.1.2) - actionpack (= 7.2.1.2) - actionview (= 7.2.1.2) - activejob (= 7.2.1.2) - activesupport (= 7.2.1.2) + actionmailer (7.2.2.1) + actionpack (= 7.2.2.1) + actionview (= 7.2.2.1) + activejob (= 7.2.2.1) + activesupport (= 7.2.2.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.1.2) - actionview (= 7.2.1.2) - activesupport (= 7.2.1.2) + actionpack (7.2.2.1) + actionview (= 7.2.2.1) + activesupport (= 7.2.2.1) nokogiri (>= 1.8.5) racc rack (>= 2.2.4, < 3.2) @@ -32,36 +32,37 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (7.2.1.2) - actionpack (= 7.2.1.2) - activerecord (= 7.2.1.2) - activestorage (= 7.2.1.2) - activesupport (= 7.2.1.2) + actiontext (7.2.2.1) + actionpack (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.1.2) - activesupport (= 7.2.1.2) + actionview (7.2.2.1) + activesupport (= 7.2.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.2.1.2) - activesupport (= 7.2.1.2) + activejob (7.2.2.1) + activesupport (= 7.2.2.1) globalid (>= 0.3.6) - activemodel (7.2.1.2) - activesupport (= 7.2.1.2) - activerecord (7.2.1.2) - activemodel (= 7.2.1.2) - activesupport (= 7.2.1.2) + activemodel (7.2.2.1) + activesupport (= 7.2.2.1) + activerecord (7.2.2.1) + activemodel (= 7.2.2.1) + activesupport (= 7.2.2.1) timeout (>= 0.4.0) - activestorage (7.2.1.2) - actionpack (= 7.2.1.2) - activejob (= 7.2.1.2) - activerecord (= 7.2.1.2) - activesupport (= 7.2.1.2) + activestorage (7.2.2.1) + actionpack (= 7.2.2.1) + activejob (= 7.2.2.1) + activerecord (= 7.2.2.1) + activesupport (= 7.2.2.1) marcel (~> 1.0) - activesupport (7.2.1.2) + activesupport (7.2.2.1) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) @@ -71,7 +72,7 @@ GEM minitest (>= 5.1) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) - acts_as_list (1.2.2) + acts_as_list (1.2.4) activerecord (>= 6.1) activesupport (>= 6.1) annotate (3.2.0) @@ -83,11 +84,12 @@ GEM ast (2.4.2) base64 (0.2.0) bcrypt (3.1.20) + benchmark (0.4.0) bigdecimal (3.1.8) - blueprinter (1.1.0) + blueprinter (1.1.2) bootsnap (1.18.4) msgpack (~> 1.2) - brakeman (6.2.1) + brakeman (6.2.2) racc builder (3.3.0) bundler-audit (0.9.2) @@ -95,7 +97,7 @@ GEM thor (~> 1.0) byebug (11.1.3) choice (0.2.0) - clearance (2.8.0) + clearance (2.9.3) actionmailer (>= 5.0) activemodel (>= 5.0) activerecord (>= 5.0) @@ -107,27 +109,28 @@ GEM concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) - database_cleaner (2.0.2) + database_cleaner (2.1.0) database_cleaner-active_record (>= 2, < 3) database_cleaner-active_record (2.2.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - date (3.3.4) + date (3.4.1) diff-lcs (1.5.1) - discard (1.3.0) - activerecord (>= 4.2, < 8) + discard (1.4.0) + activerecord (>= 4.2, < 9.0) docile (1.4.1) - doorkeeper (5.7.1) + doorkeeper (5.8.1) railties (>= 5) doorkeeper-i18n (5.2.7) doorkeeper (>= 5.2) drb (2.2.1) - dry-configurable (1.0.1) + dry-configurable (1.2.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-core (1.0.0) + dry-core (1.0.2) concurrent-ruby (~> 1.0) + logger zeitwerk (~> 2.6) dry-events (1.0.1) concurrent-ruby (~> 1.0) @@ -138,8 +141,8 @@ GEM concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-matcher (0.10.0) - dry-core (~> 1.0) + dry-matcher (1.0.0) + dry-core (~> 1.0, < 2) dry-monads (1.6.0) concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) @@ -152,12 +155,13 @@ GEM dry-logic (>= 1.4, < 2) dry-types (>= 1.7, < 2) zeitwerk (~> 2.6) - dry-transaction (0.15.0) + dry-transaction (0.16.0) dry-core (~> 1.0) dry-events (~> 1.0) - dry-matcher (~> 0.10) + dry-matcher (~> 1.0) dry-monads (~> 1.6) - dry-types (1.7.1) + dry-types (1.7.2) + bigdecimal (~> 3.0) concurrent-ruby (~> 1.0) dry-core (~> 1.0) dry-inflector (~> 1.0) @@ -186,16 +190,16 @@ GEM activesupport (>= 6.1) i18n (1.14.6) concurrent-ruby (~> 1.0) - io-console (0.7.2) - irb (1.14.0) + io-console (0.8.0) + irb (1.14.2) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.7.2) + json (2.9.0) language_server-protocol (3.17.0.3) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - logger (1.6.1) + logger (1.6.3) loofah (2.23.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -208,10 +212,10 @@ GEM method_source (1.1.0) mini_mime (1.1.5) mini_portile2 (2.8.8) - minitest (5.25.1) - msgpack (1.7.2) + minitest (5.25.4) + msgpack (1.7.5) mustache (1.1.1) - net-imap (0.4.16) + net-imap (0.5.1) date net-protocol net-pop (0.1.2) @@ -220,55 +224,56 @@ GEM timeout net-smtp (0.5.0) net-protocol - nio4r (2.7.3) - nokogiri (1.17.0) + nio4r (2.7.4) + nokogiri (1.17.2) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.6) + oj (3.16.8) bigdecimal (>= 3.0) ostruct (>= 0.2) - ostruct (0.6.0) + ostruct (0.6.1) parallel (1.26.3) - parser (3.3.5.0) + parser (3.3.6.0) ast (~> 2.4.1) racc - pg (1.5.8) - pry (0.14.2) + pg (1.5.9) + pry (0.15.0) coderay (~> 1.1) method_source (~> 1.0) pry-rails (0.3.11) pry (>= 0.13.0) - psych (5.1.2) + psych (5.2.1) + date stringio - puma (6.4.3) + puma (6.5.0) nio4r (~> 2.0) pundit (2.4.0) activesupport (>= 3.0.0) racc (1.8.1) - rack (2.2.9) + rack (2.2.10) rack-cors (1.1.1) rack (>= 2.0.0) rack-session (1.0.2) rack (< 3) rack-test (2.1.0) rack (>= 1.3) - rackup (1.0.0) + rackup (1.0.1) rack (< 3) webrick - rails (7.2.1.2) - actioncable (= 7.2.1.2) - actionmailbox (= 7.2.1.2) - actionmailer (= 7.2.1.2) - actionpack (= 7.2.1.2) - actiontext (= 7.2.1.2) - actionview (= 7.2.1.2) - activejob (= 7.2.1.2) - activemodel (= 7.2.1.2) - activerecord (= 7.2.1.2) - activestorage (= 7.2.1.2) - activesupport (= 7.2.1.2) + rails (7.2.2.1) + actioncable (= 7.2.2.1) + actionmailbox (= 7.2.2.1) + actionmailer (= 7.2.2.1) + actionpack (= 7.2.2.1) + actiontext (= 7.2.2.1) + actionview (= 7.2.2.1) + activejob (= 7.2.2.1) + activemodel (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) bundler (>= 1.15.0) - railties (= 7.2.1.2) + railties (= 7.2.2.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -278,12 +283,12 @@ GEM activesupport (>= 4.2) choice (~> 0.2.0) ruby-graphviz (~> 1.2) - rails-html-sanitizer (1.6.1) + rails-html-sanitizer (1.6.2) loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (7.2.1.2) - actionpack (= 7.2.1.2) - activesupport (= 7.2.1.2) + railties (7.2.2.1) + actionpack (= 7.2.2.1) + activesupport (= 7.2.2.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -294,64 +299,64 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rdoc (6.7.0) + rdoc (6.9.1) psych (>= 4.0.0) redis (4.8.1) - regexp_parser (2.9.2) - reline (0.5.10) + regexp_parser (2.9.3) + reline (0.5.12) io-console (~> 0.5) - rexml (3.3.9) + rexml (3.4.0) rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) rspec-mocks (~> 3.13.0) - rspec-core (3.13.1) + rspec-core (3.13.2) rspec-support (~> 3.13.0) rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.1) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (6.1.5) - actionpack (>= 6.1) - activesupport (>= 6.1) - railties (>= 6.1) + rspec-rails (7.1.0) + actionpack (>= 7.0) + activesupport (>= 7.0) + railties (>= 7.0) rspec-core (~> 3.13) rspec-expectations (~> 3.13) rspec-mocks (~> 3.13) rspec-support (~> 3.13) - rspec-support (3.13.1) + rspec-support (3.13.2) rspec_api_documentation (6.1.0) activesupport (>= 3.0.0) mustache (~> 1.0, >= 0.99.4) rspec (~> 3.0) - rubocop (1.66.1) + rubocop (1.69.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.2, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.36.2, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.3) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.37.0) parser (>= 3.3.1.0) - rubocop-performance (1.22.1) + rubocop-performance (1.23.0) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.26.1) + rubocop-rails (2.27.0) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (3.0.5) + rubocop-rspec (3.3.0) rubocop (~> 1.61) ruby-graphviz (1.2.5) rexml ruby-progressbar (1.13.0) - securerandom (0.3.1) + securerandom (0.4.1) sidekiq (6.5.12) connection_pool (>= 2.2.5, < 3) rack (~> 2.0) @@ -372,25 +377,27 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - state_machines (0.5.0) - state_machines-activemodel (0.8.0) - activemodel (>= 5.1) - state_machines (>= 0.5.0) + state_machines (0.6.0) + state_machines-activemodel (0.9.0) + activemodel (>= 6.0) + state_machines (>= 0.6.0) state_machines-activerecord (0.6.0) activerecord (>= 4.1) state_machines-activemodel (>= 0.5.0) - stringio (3.1.1) + stringio (3.1.2) thor (1.3.2) - timeout (0.4.1) + timeout (0.4.3) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.6.0) - useragent (0.16.10) - webrick (1.8.2) + unicode-display_width (3.1.2) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + useragent (0.16.11) + webrick (1.9.1) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.6.18) + zeitwerk (2.7.1) PLATFORMS ruby @@ -420,7 +427,7 @@ DEPENDENCIES puma (~> 6.4) pundit (~> 2.1) rack-cors (~> 1.1) - rails (~> 7.2.1.1) + rails (~> 7.2.2.1) rails-erd (~> 1.6) rspec-rails rspec_api_documentation (~> 6.1) diff --git a/app/blueprinter/user_blueprint.rb b/app/blueprinter/user_blueprint.rb index 91ff408..6b6e123 100644 --- a/app/blueprinter/user_blueprint.rb +++ b/app/blueprinter/user_blueprint.rb @@ -2,5 +2,5 @@ class UserBlueprint < Base # Fields - fields :email, :role, :first_name, :last_name, :laboratory + fields :email, :first_name, :last_name end diff --git a/app/blueprinter/users/grower_blueprint.rb b/app/blueprinter/users/grower_blueprint.rb deleted file mode 100644 index 7f2c9b1..0000000 --- a/app/blueprinter/users/grower_blueprint.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class Users::GrowerBlueprint < UserBlueprint -end diff --git a/app/blueprinter/users/requester_blueprint.rb b/app/blueprinter/users/requester_blueprint.rb deleted file mode 100644 index 3bd4de0..0000000 --- a/app/blueprinter/users/requester_blueprint.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class Users::RequesterBlueprint < UserBlueprint -end diff --git a/app/controllers/api/v1/me_controller.rb b/app/controllers/api/v1/me_controller.rb index 4372b79..19b5461 100644 --- a/app/controllers/api/v1/me_controller.rb +++ b/app/controllers/api/v1/me_controller.rb @@ -32,10 +32,6 @@ def destroy private def update_params - if current_user.requester? - params.permit(%i[first_name last_name laboratory]) - else - params.permit(%i[first_name last_name]) - end + params.permit(%i[first_name last_name]) end end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 0f639b7..83f60d3 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -6,4 +6,39 @@ def index authorize users render json: apply_fetcheable(users).to_blueprint end + + def show + user = policy_scope(User).find(params[:id]) + authorize user + render json: user.to_blueprint + end + + def create + user = User.new(create_params) + + authorize user + + if user.save + render json: user.to_blueprint, status: :created + else + render json: { errors: user.errors.full_messages }, status: :unprocessable_entity + end + end + + def destroy + user = policy_scope(User).find(params[:id]) + authorize user + + if user.destroy + render json: { message: 'User deleted' }, status: :ok + else + render json: { errors: user.errors.full_messages }, status: :unprocessable_entity + end + end + + private + + def create_params + params.permit(:email, :password, :password_confirmation, :first_name, :last_name) + end end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 82edf47..c0a27b4 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -64,11 +64,9 @@ def render_validation_error(model) end def unauthorized(exception) - if exception.record.is_a?(ActiveRecord::Base) && exception.record.errors.present? - return render_error(exception.record, code: 403) - end + return unless exception.record.is_a?(ActiveRecord::Base) && exception.record.errors.present? - render_error(exception.message, code: 403) + render_error(exception.record, code: 403) end def not_found(exception) diff --git a/app/models/building.rb b/app/models/building.rb index d178a51..802be00 100644 --- a/app/models/building.rb +++ b/app/models/building.rb @@ -14,7 +14,7 @@ class Building < ApplicationRecord # # id :bigint not null, primary key # name :string -# description :string # created_at :datetime not null # updated_at :datetime not null +# description :text # diff --git a/app/models/request.rb b/app/models/request.rb index ed04fdf..05db772 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -89,9 +89,9 @@ class Request < ApplicationRecord # photoperiod :integer # created_at :datetime not null # updated_at :datetime not null -# requester_first_name :string default(""), not null -# requester_last_name :string default(""), not null -# requester_email :string default(""), not null +# requester_first_name :string not null +# requester_last_name :string not null +# requester_email :string not null # laboratory :string # # Indexes diff --git a/app/models/user.rb b/app/models/user.rb index c73b913..b3d25d1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,12 +7,6 @@ class User < ApplicationRecord # Discard include Discard::Model - # Enumerize - extend Enumerize - enumerize :role, - in: %i[requester grower], - predicates: true - # Validations validates :email, presence: true, @@ -28,9 +22,7 @@ class User < ApplicationRecord presence: true, on: :create - validates :role, - :type, - :first_name, + validates :first_name, :last_name, presence: true @@ -64,7 +56,6 @@ def anonymize self.remember_token = 'anonymized' self.first_name = nil self.last_name = nil - self.laboratory = nil save(validate: false) end @@ -79,11 +70,8 @@ def anonymize # encrypted_password :string(128) not null # confirmation_token :string(128) # remember_token :string(128) not null -# role :string # first_name :string # last_name :string -# type :string -# laboratory :string # created_at :datetime not null # updated_at :datetime not null # discarded_at :datetime diff --git a/app/models/users/grower.rb b/app/models/users/grower.rb index d6d43aa..2b99557 100644 --- a/app/models/users/grower.rb +++ b/app/models/users/grower.rb @@ -18,11 +18,8 @@ class Users::Grower < User # encrypted_password :string(128) not null # confirmation_token :string(128) # remember_token :string(128) not null -# role :string # first_name :string # last_name :string -# type :string -# laboratory :string # created_at :datetime not null # updated_at :datetime not null # discarded_at :datetime diff --git a/app/models/users/requester.rb b/app/models/users/requester.rb deleted file mode 100644 index a4a3ace..0000000 --- a/app/models/users/requester.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -class Users::Requester < User -end - -# == Schema Information -# -# Table name: users -# -# id :bigint not null, primary key -# email :string not null -# encrypted_password :string(128) not null -# confirmation_token :string(128) -# remember_token :string(128) not null -# role :string -# first_name :string -# last_name :string -# type :string -# laboratory :string -# created_at :datetime not null -# updated_at :datetime not null -# discarded_at :datetime -# -# Indexes -# -# index_users_on_discarded_at (discarded_at) -# index_users_on_email (email) UNIQUE -# index_users_on_remember_token (remember_token) -# diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 30dbb74..83d2cf2 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -5,8 +5,6 @@ class ApplicationPolicy attr_reader :user, :record - delegate :requester?, :grower?, to: :user - def initialize(user, record) @user = user @record = record @@ -25,8 +23,6 @@ def destroy?; end class Scope attr_reader :user, :scope - delegate :requester?, :grower?, to: :user - def initialize(user, scope) @user = user @scope = scope diff --git a/app/policies/bench_policy.rb b/app/policies/bench_policy.rb index 12b12b6..beb9331 100644 --- a/app/policies/bench_policy.rb +++ b/app/policies/bench_policy.rb @@ -2,24 +2,22 @@ class BenchPolicy < ApplicationPolicy def index? - grower? + true end def show? - grower? + true end def create? - grower? + true end def update? - grower? + true end def destroy? - return false unless grower? - return true if record.request_distributions.empty? record.errors.add(:request_distributions, 'can\'t delete a bench with ongoing requests') @@ -28,7 +26,7 @@ def destroy? class Scope < Scope def resolve - grower? ? scope.all : scope.none + scope.all end end end diff --git a/app/policies/building_policy.rb b/app/policies/building_policy.rb index bf7bd71..3ac5640 100644 --- a/app/policies/building_policy.rb +++ b/app/policies/building_policy.rb @@ -2,24 +2,22 @@ class BuildingPolicy < ApplicationPolicy def index? - grower? + true end def show? - grower? + true end def create? - grower? + true end def update? - grower? + true end def destroy? - return false unless grower? - return true if record.greenhouses.flat_map(&:benches).flat_map(&:request_distributions).empty? record.errors.add(:request_distributions, 'can\'t delete a building with ongoing requests') @@ -28,7 +26,7 @@ def destroy? class Scope < Scope def resolve - grower? ? scope.all : scope.none + scope.all end end end diff --git a/app/policies/greenhouse_policy.rb b/app/policies/greenhouse_policy.rb index 965eb7f..189ca83 100644 --- a/app/policies/greenhouse_policy.rb +++ b/app/policies/greenhouse_policy.rb @@ -2,24 +2,22 @@ class GreenhousePolicy < ApplicationPolicy def index? - grower? + true end def show? - grower? + true end def create? - grower? + true end def update? - grower? + true end def destroy? - return false unless grower? - return true if record.benches.flat_map(&:request_distributions).empty? record.errors.add(:request_distributions, 'can\'t delete a greenhouse with ongoing requests') @@ -28,7 +26,7 @@ def destroy? class Scope < Scope def resolve - grower? ? scope.all : scope.none + scope.all end end end diff --git a/app/policies/plant_policy.rb b/app/policies/plant_policy.rb index b71879f..4e8c14b 100644 --- a/app/policies/plant_policy.rb +++ b/app/policies/plant_policy.rb @@ -10,16 +10,14 @@ def show? end def create? - grower? + true end def update? - grower? + true end def destroy? - return false unless grower? - return true if record.plant_stages.flat_map(&:request_distributions).empty? record.errors.add(:request_distributions, 'can\'t delete a plant with ongoing requests') diff --git a/app/policies/pot_policy.rb b/app/policies/pot_policy.rb index c2fac5f..ccca9b7 100644 --- a/app/policies/pot_policy.rb +++ b/app/policies/pot_policy.rb @@ -2,20 +2,18 @@ class PotPolicy < ApplicationPolicy def index? - grower? + true end def show? - grower? + true end def create? - grower? + true end def update? - return false unless grower? - return true if record.request_distributions.empty? record.errors.add(:request_distributions, 'can\'t update a pot with ongoing requests') @@ -23,8 +21,6 @@ def update? end def destroy? - return false unless grower? - return true if record.request_distributions.empty? record.errors.add(:request_distributions, 'can\'t delete a pot with ongoing requests') @@ -33,7 +29,7 @@ def destroy? class Scope < Scope def resolve - grower? ? scope.all : scope.none + scope.all end end end diff --git a/app/policies/request_distribution_policy.rb b/app/policies/request_distribution_policy.rb index 17e9df9..b6becdf 100644 --- a/app/policies/request_distribution_policy.rb +++ b/app/policies/request_distribution_policy.rb @@ -2,24 +2,22 @@ class RequestDistributionPolicy < ApplicationPolicy def index? - grower? + true end def show? - grower? + true end def create? - grower? + true end def update? - grower? + true end def destroy? - return false unless grower? - return true unless record.request.accepted? return true if record.request.request_distributions.count > 1 @@ -30,7 +28,7 @@ def destroy? class Scope < Scope def resolve - grower? ? scope.all : scope.none + scope.all end end end diff --git a/app/policies/request_policy.rb b/app/policies/request_policy.rb index c0b2819..b033a47 100644 --- a/app/policies/request_policy.rb +++ b/app/policies/request_policy.rb @@ -6,32 +6,30 @@ def index? end def requests_to_handle_count? - grower? + true end def show? - grower? + true end def accept? - grower? + true end def refuse? - grower? + true end def cancel? - grower? + true end def complete? - grower? + true end def destroy? - return false unless grower? - if record.pending? true else diff --git a/app/policies/shape_policy.rb b/app/policies/shape_policy.rb index 027bde4..c1920f4 100644 --- a/app/policies/shape_policy.rb +++ b/app/policies/shape_policy.rb @@ -2,6 +2,6 @@ class ShapePolicy < ApplicationPolicy def index? - grower? + true end end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 34d31e3..60d2325 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -9,6 +9,10 @@ def show? true end + def create? + true + end + def update? true end @@ -19,7 +23,7 @@ def destroy? class Scope < Scope def resolve - grower? ? scope.all : scope.where(id: user.id) + scope.all end end end diff --git a/app/policies/users/grower_policy.rb b/app/policies/users/grower_policy.rb deleted file mode 100644 index ffab1b0..0000000 --- a/app/policies/users/grower_policy.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class Users::GrowerPolicy < UserPolicy -end diff --git a/app/policies/users/requester_policy.rb b/app/policies/users/requester_policy.rb deleted file mode 100644 index 429bbe7..0000000 --- a/app/policies/users/requester_policy.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class Users::RequesterPolicy < UserPolicy -end diff --git a/config/routes.rb b/config/routes.rb index ef5daf8..258e335 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,7 +16,7 @@ post :accept, on: :member end - resources :users, only: :index + resources :users, only: %i[index show create destroy] resources :pots, only: %i[index show create update destroy] diff --git a/db/migrate/20241216104204_remove_attribute_from_users.rb b/db/migrate/20241216104204_remove_attribute_from_users.rb new file mode 100644 index 0000000..462a02c --- /dev/null +++ b/db/migrate/20241216104204_remove_attribute_from_users.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class RemoveAttributeFromUsers < ActiveRecord::Migration[7.2] + def up + change_table :users, bulk: true do |t| + t.remove :laboratory, :role, :type + end + end + + def down + change_table :users, bulk: true do |t| + t.string :laboratory + t.string :role + t.string :type + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 8c2252c..f8ebb91 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_12_04_211606) do +ActiveRecord::Schema[7.2].define(version: 2024_12_16_104204) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -26,9 +26,9 @@ create_table "buildings", force: :cascade do |t| t.string "name" - t.string "description" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.text "description" end create_table "greenhouses", force: :cascade do |t| @@ -138,9 +138,9 @@ t.integer "photoperiod" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "requester_first_name", default: "", null: false - t.string "requester_last_name", default: "", null: false - t.string "requester_email", default: "", null: false + t.string "requester_first_name", null: false + t.string "requester_last_name", null: false + t.string "requester_email", null: false t.string "laboratory" t.index ["handler_id"], name: "index_requests_on_handler_id" t.index ["plant_stage_id"], name: "index_requests_on_plant_stage_id" @@ -151,11 +151,8 @@ t.string "encrypted_password", limit: 128, null: false t.string "confirmation_token", limit: 128 t.string "remember_token", limit: 128, null: false - t.string "role" t.string "first_name" t.string "last_name" - t.string "type" - t.string "laboratory" t.datetime "created_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false t.datetime "discarded_at", precision: nil diff --git a/db/seeds.rb b/db/seeds.rb index 24d7d29..f43b359 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -13,19 +13,7 @@ confidential: false ) - # Users - Users::Requester.create!( - role: :requester, - email: 'dev+requester@progeser.com', - password: 'password', - password_confirmation: 'password', - first_name: 'Requester', - last_name: 'ProGeSer', - laboratory: 'My test lab' - ) - Users::Grower.create!( - role: :grower, email: 'dev+grower@progeser.com', password: 'password', password_confirmation: 'password', @@ -33,17 +21,6 @@ last_name: 'ProGeSer' ) - discarded_user = Users::Requester.create!( - role: :requester, - email: 'discarded_requester@progeser.com', - password: 'password', - password_confirmation: 'password', - first_name: 'Discarded', - last_name: 'User', - laboratory: 'My test lab' - ) - discarded_user.discard - # Pots Pot.create!( name: 'My square pot', diff --git a/erd.pdf b/erd.pdf index 86e4f29..2aa7dba 100644 Binary files a/erd.pdf and b/erd.pdf differ diff --git a/spec/acceptance/api/v1/me_controller_spec.rb b/spec/acceptance/api/v1/me_controller_spec.rb index 09fdade..fd741fa 100644 --- a/spec/acceptance/api/v1/me_controller_spec.rb +++ b/spec/acceptance/api/v1/me_controller_spec.rb @@ -44,7 +44,6 @@ expect(response_body).to eq(user.to_blueprint) expect(user.first_name).to eq(first_name) expect(user.last_name).to eq(last_name) - expect(user.laboratory).to eq(laboratory) end end @@ -62,7 +61,6 @@ expect(user.encrypted_password).to eq('anonymized') expect(user.first_name).to be_nil expect(user.last_name).to be_nil - expect(user.laboratory).to be_nil end end end diff --git a/spec/acceptance/api/v1/users_controller_spec.rb b/spec/acceptance/api/v1/users_controller_spec.rb index f075093..3a3df53 100644 --- a/spec/acceptance/api/v1/users_controller_spec.rb +++ b/spec/acceptance/api/v1/users_controller_spec.rb @@ -44,4 +44,65 @@ expect(JSON.parse(response_body).count).to eq(User.count) end end + + get '/api/v1/users/:id' do + parameter :id, 'The user id', with_example: true, type: :integer + + let(:id) { user.id } + + example 'Get a user' do + authentication :basic, "Bearer #{user_token.token}" + + do_request + + expect(status).to eq(200) + + expect(JSON.parse(response_body)['id']).to eq(user.id) + expect(JSON.parse(response_body)['email']).to eq(user.email) + expect(JSON.parse(response_body)['first_name']).to eq(user.first_name) + expect(JSON.parse(response_body)['last_name']).to eq(user.last_name) + end + end + + post '/api/v1/users' do + parameter :email, 'The user email', with_example: true + parameter :first_name, 'The user first name', with_example: true + parameter :last_name, 'The user last name', with_example: true + parameter :password, 'The user password', with_example: true + parameter :password_confirmation, 'The user password confirmation', with_example: true + + let(:email) { 'test@test.com' } + let(:first_name) { 'Test' } + let(:last_name) { 'User' } + let(:password) { 'password' } + let(:password_confirmation) { 'password' } + + let(:raw_post) { params.to_json } + + example 'Create a user' do + authentication :basic, "Bearer #{user_token.token}" + + do_request + + expect(status).to eq(201) + expect(JSON.parse(response_body)['email']).to eq(email) + expect(JSON.parse(response_body)['first_name']).to eq(first_name) + expect(JSON.parse(response_body)['last_name']).to eq(last_name) + end + end + + delete '/api/v1/users/:id' do + parameter :id, 'The user id', with_example: true, type: :integer + + let(:id) { user.id } + + example 'Delete a user' do + authentication :basic, "Bearer #{user_token.token}" + + do_request + + expect(status).to eq(200) + expect(JSON.parse(response_body)['message']).to eq('User deleted') + end + end end diff --git a/spec/requests/api/v1/benches_spec.rb b/spec/requests/api/v1/benches_spec.rb index 7e22fee..cd01a01 100644 --- a/spec/requests/api/v1/benches_spec.rb +++ b/spec/requests/api/v1/benches_spec.rb @@ -30,44 +30,9 @@ end end end - - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get benches' do - get("/api/v1/greenhouses/#{greenhouse.id}/benches", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end - - describe 'GET api/v1/benches/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get a bench' do - get("/api/v1/benches/#{bench.id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end end describe 'POST api/v1/greenhouses/:greenhouse_id/benches' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t create a bench' do - post("/api/v1/greenhouses/#{greenhouse.id}/benches", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'can\'t have a negative dimension' do @@ -130,17 +95,6 @@ end describe 'PUT api/v1/benches/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t update a bench' do - put("/api/v1/benches/#{bench.id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'can\'t have an area lower than the sum of distributions areas' do @@ -196,17 +150,6 @@ end end - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t delete a bench' do - delete("/api/v1/benches/#{bench.id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do before do diff --git a/spec/requests/api/v1/buildings_spec.rb b/spec/requests/api/v1/buildings_spec.rb index ed28914..12c13be 100644 --- a/spec/requests/api/v1/buildings_spec.rb +++ b/spec/requests/api/v1/buildings_spec.rb @@ -30,44 +30,9 @@ end end end - - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get buildings' do - get('/api/v1/buildings', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end - - describe 'GET api/v1/buildings/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get a building' do - get("/api/v1/buildings/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end end describe 'POST api/v1/buildings' do - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t create a building' do - post('/api/v1/buildings', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when validation fails' do it_behaves_like 'with authenticated grower' do it 'returns validation error for invalid building data' do @@ -85,17 +50,6 @@ end describe 'PUT api/v1/buildings/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t update a building' do - put("/api/v1/buildings/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when validation fails' do it_behaves_like 'with authenticated grower' do it 'returns validation error for invalid update data' do @@ -113,16 +67,6 @@ end describe 'DELETE api/v1/buildings/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t delete a building' do - delete("/api/v1/buildings/#{id}", headers:) - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when validation fails' do it_behaves_like 'with authenticated grower' do before do diff --git a/spec/requests/api/v1/greenhouses_spec.rb b/spec/requests/api/v1/greenhouses_spec.rb index 9f1cbe8..9d848a7 100644 --- a/spec/requests/api/v1/greenhouses_spec.rb +++ b/spec/requests/api/v1/greenhouses_spec.rb @@ -30,43 +30,9 @@ end end end - - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get greenhouses' do - get("/api/v1/buildings/#{building.id}/greenhouses", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end - - describe 'GET api/v1/greenhouses/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get a greenhouse' do - get("/api/v1/greenhouses/#{greenhouse.id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end end describe 'POST api/v1/greenhouses' do - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t create a greenhouse' do - post("/api/v1/buildings/#{building.id}/greenhouses", headers:) - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'fails to create a greenhouse with invalid params' do @@ -89,17 +55,6 @@ end describe 'PUT api/v1/greenhouses/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t update a greenhouse' do - put("/api/v1/greenhouses/#{greenhouse.id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'fails to update a greenhouse with invalid params' do @@ -133,17 +88,6 @@ end end - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t delete a greenhouse' do - delete("/api/v1/greenhouses/#{greenhouse.id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do before do diff --git a/spec/requests/api/v1/me_spec.rb b/spec/requests/api/v1/me_spec.rb index 0c0631f..d126932 100644 --- a/spec/requests/api/v1/me_spec.rb +++ b/spec/requests/api/v1/me_spec.rb @@ -32,8 +32,7 @@ headers:, params: { first_name: 'my new first name', - last_name: 'my new last name', - laboratory: 'laboratory' + last_name: 'my new last name' } ) @@ -43,7 +42,6 @@ expect(response.body).to eq(user.to_blueprint) expect(user.first_name).to eq('my new first name') expect(user.last_name).to eq('my new last name') - expect(user.laboratory).to be_nil end end diff --git a/spec/requests/api/v1/plants_spec.rb b/spec/requests/api/v1/plants_spec.rb index a45f5f3..674d9e4 100644 --- a/spec/requests/api/v1/plants_spec.rb +++ b/spec/requests/api/v1/plants_spec.rb @@ -34,17 +34,6 @@ end describe 'POST api/v1/plants' do - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t create a plant' do - post('/api/v1/plants', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do # See comment on validation in app/models/plant.rb @@ -80,17 +69,6 @@ end describe 'PUT api/v1/plants/:id' do - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t update a plant' do - put("/api/v1/plants/#{id}", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do # See comment on validation in app/models/plant.rb @@ -143,15 +121,6 @@ describe 'DELETE api/v1/plants/:id' do context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t delete a plant' do - delete("/api/v1/plants/#{id}", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - it_behaves_like 'with authenticated grower' do it 'can\'t delete a plant with ongoing requests' do delete("/api/v1/plants/#{id}", headers:) diff --git a/spec/requests/api/v1/pots_spec.rb b/spec/requests/api/v1/pots_spec.rb index 6338bbb..7cddeab 100644 --- a/spec/requests/api/v1/pots_spec.rb +++ b/spec/requests/api/v1/pots_spec.rb @@ -31,30 +31,6 @@ end end end - - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get pots' do - get('/api/v1/pots', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end - - describe 'GET api/v1/pots/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get a pot' do - get("/api/v1/pots/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end end describe 'POST api/v1/pots' do @@ -260,17 +236,6 @@ end end - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t create a pot' do - post('/api/v1/pots', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'fails to create a pot with dimensions & invalid shape' do @@ -357,17 +322,6 @@ end end end - - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t update a pot' do - put("/api/v1/pots/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end end describe 'DELETE api/v1/pots/:id' do @@ -382,17 +336,6 @@ end end - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t delete a pot' do - delete("/api/v1/pots/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do before do diff --git a/spec/requests/api/v1/request_distributions_spec.rb b/spec/requests/api/v1/request_distributions_spec.rb index 2e5b746..f8b5f78 100644 --- a/spec/requests/api/v1/request_distributions_spec.rb +++ b/spec/requests/api/v1/request_distributions_spec.rb @@ -33,30 +33,6 @@ end end end - - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get request distributions' do - get('/api/v1/requests/2/request_distributions', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end - - describe 'GET api/v1/request_distributions/:id' do - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get a request distribution' do - get("/api/v1/request_distributions/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end end describe 'POST api/v1/requests/:request_id/request_distributions' do @@ -113,17 +89,6 @@ end end - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t create a request distribution' do - post("/api/v1/requests/#{request_id}/request_distributions", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'distributions can\'t have a sum of areas greater than their bench area' do @@ -206,17 +171,6 @@ end end - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t update a request distribution' do - put("/api/v1/request_distributions/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'fails to update a request distribution with missing params' do @@ -251,17 +205,6 @@ end end - context 'when 404' do - it_behaves_like 'with authenticated requester' do - it 'can\'t delete a request distribution' do - delete("/api/v1/request_distributions/#{id}", headers:) - - expect(status).to eq(404) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'fails to delete a request distribution' do diff --git a/spec/requests/api/v1/requests_spec.rb b/spec/requests/api/v1/requests_spec.rb index 6495176..05f489f 100644 --- a/spec/requests/api/v1/requests_spec.rb +++ b/spec/requests/api/v1/requests_spec.rb @@ -108,19 +108,6 @@ end end - describe 'GET api/v1/requests/requests_to_handle_count' do - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get number of requests to handle' do - get('/api/v1/requests/requests_to_handle_count', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end - describe 'POST api/v1/requests' do context 'when 201' do it_behaves_like 'with authenticated grower' do @@ -321,17 +308,6 @@ let!(:request) { requests(:request2) } let!(:id) { request.id } - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t accept a request' do - post("/api/v1/requests/#{id}/accept", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'can\'t accept a non-pending request' do @@ -367,17 +343,6 @@ let!(:request) { requests(:request2) } let!(:id) { request.id } - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t refuse a request' do - post("/api/v1/requests/#{id}/refuse", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'can\'t refuse a non-pending request' do @@ -414,17 +379,6 @@ let!(:request) { requests(:request2) } let!(:id) { request.id } - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t complete a request' do - post("/api/v1/requests/#{id}/complete", headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - context 'when 422' do it_behaves_like 'with authenticated grower' do it 'can\'t complete a non-accepted request' do diff --git a/spec/requests/api/v1/shapes_spec.rb b/spec/requests/api/v1/shapes_spec.rb deleted file mode 100644 index 1208492..0000000 --- a/spec/requests/api/v1/shapes_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe 'Api/V1/Shapes', type: :request do - describe 'GET api/v1/shapes' do - context 'when 403' do - it_behaves_like 'with authenticated requester' do - it 'can\'t get shapes' do - get('/api/v1/shapes', headers:) - - expect(status).to eq(403) - expect(response.parsed_body.dig('error', 'message')).not_to be_blank - end - end - end - end -end diff --git a/spec/requests/api/v1/users_spec.rb b/spec/requests/api/v1/users_spec.rb index e276c04..3c7380a 100644 --- a/spec/requests/api/v1/users_spec.rb +++ b/spec/requests/api/v1/users_spec.rb @@ -27,15 +27,114 @@ expect(response.headers['Pagination-Total-Count']).to eq(3) end end + end + end - it_behaves_like 'with authenticated requester' do - it 'gets the authenticated user only' do - get('/api/v1/users', headers:) + describe 'GET api/v1/users/:id' do + context 'when 404' do + it_behaves_like 'with authenticated grower' do + it 'gets a user' do + get( + '/api/v1/users/0', + headers: + ) - expect(status).to eq(200) + expect(status).to eq(404) + end + end + end + + context 'when 401' do + it 'gets a user' do + get( + '/api/v1/users/0', + headers: + ) + + expect(status).to eq(401) + end + end + end + + describe 'POST api/v1/users' do + context 'when 422' do + it_behaves_like 'with authenticated grower' do + it 'returns validation errors' do + post( + '/api/v1/users', + headers:, + params: { + user: { + email: '', + password: '', + password_confirmation: '', + first_name: '', + last_name: '' + } + } + ) + expect(status).to eq(422) + end + end + end + + context 'when 401' do + it 'returns unauthorized error' do + post( + '/api/v1/users', + headers: {}, + params: { + user: { + email: 'test@test.com', + password: 'password', + password_confirmation: 'password', + first_name: 'Test', + last_name: 'User' + } + } + ) + + expect(status).to eq(401) + end + end + end + + describe 'DELETE api/v1/users/:id' do + context 'when 404' do + it_behaves_like 'with authenticated grower' do + it 'returns not found error' do + delete( + '/api/v1/users/0', + headers: + ) + + expect(status).to eq(404) + end + end + end + + context 'when 401' do + it 'returns unauthorized error' do + delete( + '/api/v1/users/1', + headers: {} + ) + + expect(status).to eq(401) + end + end + + context 'when 422' do + it_behaves_like 'with authenticated grower' do + it 'fails to delete user' do + allow_any_instance_of(User).to receive(:destroy).and_return(false) + + delete( + '/api/v1/users/1', + headers: + ) - expect(response.parsed_body.count).to eq(1) - expect(response.parsed_body.first['id']).to eq(user.id) + expect(status).to eq(422) end end end diff --git a/test/fixtures/buildings.yml b/test/fixtures/buildings.yml index 0557806..48be6ac 100644 --- a/test/fixtures/buildings.yml +++ b/test/fixtures/buildings.yml @@ -32,7 +32,7 @@ building2: # # id :bigint not null, primary key # name :string -# description :string # created_at :datetime not null # updated_at :datetime not null +# description :text # diff --git a/test/fixtures/requests.yml b/test/fixtures/requests.yml index 02b9269..c6a4b18 100644 --- a/test/fixtures/requests.yml +++ b/test/fixtures/requests.yml @@ -71,9 +71,9 @@ request2: # photoperiod :integer # created_at :datetime not null # updated_at :datetime not null -# requester_first_name :string default(""), not null -# requester_last_name :string default(""), not null -# requester_email :string default(""), not null +# requester_first_name :string not null +# requester_last_name :string not null +# requester_email :string not null # laboratory :string # # Indexes diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 16de608..b29f841 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -5,11 +5,8 @@ user2: encrypted_password: "$2a$12$/1.8Kj10CXryn3VCJea3WuXjxYQTELbrSSfsYrzzIpWGMk73y.Pqi" confirmation_token: remember_token: 5bf6d687b34c92ec9473c212bdc335a3477e7fe9 - role: grower last_name: ProGeSer first_name: Grower - type: Users::Grower - laboratory: created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2019-10-30 16:57:33.569980000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone @@ -26,11 +23,8 @@ user1: encrypted_password: "$2a$12$ogAZLpfd7v6dDablqAc.QefwbWLO/AHj/P.4OtrQUz3w4dUJxWCHy" confirmation_token: remember_token: b65a042d9bbbdc77243c27b1cff7d4ecb5badf6e - role: requester last_name: ProGeSer first_name: Requester - type: Users::Requester - laboratory: My test lab created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2019-10-30 16:57:33.316242000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone @@ -47,11 +41,8 @@ user3: encrypted_password: anonymized confirmation_token: remember_token: anonymized - role: requester - last_name: + last_name: first_name: - type: Users::Requester - laboratory: My test lab created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2019-10-31 15:40:41.545001000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone @@ -75,11 +66,8 @@ user3: # encrypted_password :string(128) not null # confirmation_token :string(128) # remember_token :string(128) not null -# role :string # first_name :string # last_name :string -# type :string -# laboratory :string # created_at :datetime not null # updated_at :datetime not null # discarded_at :datetime diff --git a/test/models/building_test.rb b/test/models/building_test.rb index c24d02d..c79f86f 100644 --- a/test/models/building_test.rb +++ b/test/models/building_test.rb @@ -32,7 +32,7 @@ def setup # # id :bigint not null, primary key # name :string -# description :string # created_at :datetime not null # updated_at :datetime not null +# description :text # diff --git a/test/models/request_test.rb b/test/models/request_test.rb index b90a60d..5167a7e 100644 --- a/test/models/request_test.rb +++ b/test/models/request_test.rb @@ -137,9 +137,9 @@ def setup # photoperiod :integer # created_at :datetime not null # updated_at :datetime not null -# requester_first_name :string default(""), not null -# requester_last_name :string default(""), not null -# requester_email :string default(""), not null +# requester_first_name :string not null +# requester_last_name :string not null +# requester_email :string not null # laboratory :string # # Indexes diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 59e2e8f..16d3609 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -17,11 +17,8 @@ class UserTest < ActiveSupport::TestCase # encrypted_password :string(128) not null # confirmation_token :string(128) # remember_token :string(128) not null -# role :string # first_name :string # last_name :string -# type :string -# laboratory :string # created_at :datetime not null # updated_at :datetime not null # discarded_at :datetime diff --git a/test/models/users/grower_test.rb b/test/models/users/grower_test.rb index bbc4788..b54204e 100644 --- a/test/models/users/grower_test.rb +++ b/test/models/users/grower_test.rb @@ -38,18 +38,6 @@ def setup assert_not_empty @user.errors[:password] end - test 'invalid without role' do - @user.role = nil - assert_not @user.valid? - assert_not_empty @user.errors[:role] - end - - test 'invalid without type' do - @user.type = nil - assert_not @user.valid? - assert_not_empty @user.errors[:type] - end - test 'invalid without first_name' do @user.first_name = nil assert_not @user.valid? @@ -61,23 +49,6 @@ def setup assert_not @user.valid? assert_not_empty @user.errors[:last_name] end - - test 'valid without laboratory' do - @user.laboratory = nil - assert @user.valid?, @user.errors.messages - end - - # Enumerize - test 'invalid with incorrect role value' do - @user.role = 'foo' - assert_not @user.valid? - assert_not_empty @user.errors[:role] - end - - test 'predicate methods' do - assert @user.grower? - assert_not @user.requester? - end end # == Schema Information @@ -89,11 +60,8 @@ def setup # encrypted_password :string(128) not null # confirmation_token :string(128) # remember_token :string(128) not null -# role :string # first_name :string # last_name :string -# type :string -# laboratory :string # created_at :datetime not null # updated_at :datetime not null # discarded_at :datetime diff --git a/test/models/users/requester_test.rb b/test/models/users/requester_test.rb deleted file mode 100644 index feba93e..0000000 --- a/test/models/users/requester_test.rb +++ /dev/null @@ -1,101 +0,0 @@ -# frozen_string_literal: true - -require 'test_helper' - -class Users::RequesterTest < ActiveSupport::TestCase - # Setups - def setup - @user = users(:user1) - end - - # Validations - test 'valid user' do - assert @user.valid?, @user.errors.messages - end - - test 'invalid without email' do - @user.email = nil - assert_not @user.valid? - assert_not_empty @user.errors[:email] - end - - test 'invalid with existing email' do - @user.email = users(:user2).email - assert_not @user.valid? - assert_not_empty @user.errors[:email] - end - - test 'invalid with incorrect email value' do - @user.email = 'foo' - assert_not @user.valid? - assert_not_empty @user.errors[:email] - end - - test 'invalid without password' do - @user.password = nil - @user.encrypted_password = nil - assert_not @user.valid? - assert_not_empty @user.errors[:password] - end - - test 'invalid without role' do - @user.role = nil - assert_not @user.valid? - assert_not_empty @user.errors[:role] - end - - test 'invalid without type' do - @user.type = nil - assert_not @user.valid? - assert_not_empty @user.errors[:type] - end - - test 'invalid without first_name' do - @user.first_name = nil - assert_not @user.valid? - assert_not_empty @user.errors[:first_name] - end - - test 'invalid without last_name' do - @user.last_name = nil - assert_not @user.valid? - assert_not_empty @user.errors[:last_name] - end - - # Enumerize - test 'invalid with incorrect role value' do - @user.role = 'foo' - assert_not @user.valid? - assert_not_empty @user.errors[:role] - end - - test 'predicate methods' do - assert @user.requester? - assert_not @user.grower? - end -end - -# == Schema Information -# -# Table name: users -# -# id :bigint not null, primary key -# email :string not null -# encrypted_password :string(128) not null -# confirmation_token :string(128) -# remember_token :string(128) not null -# role :string -# first_name :string -# last_name :string -# type :string -# laboratory :string -# created_at :datetime not null -# updated_at :datetime not null -# discarded_at :datetime -# -# Indexes -# -# index_users_on_discarded_at (discarded_at) -# index_users_on_email (email) UNIQUE -# index_users_on_remember_token (remember_token) -#