diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 669c7518..91601b0b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,9 +14,6 @@ class ApplicationController < ActionController::Base @current_user ||= ExternalUser.find_by(id: session[:external_user_id]) || login_from_session || login_from_other_sources end - def help - end - def render_not_authorized redirect_to(:root, alert: t('application.not_authorized')) end diff --git a/app/controllers/code_ocean/errors_controller.rb b/app/controllers/code_ocean/errors_controller.rb new file mode 100644 index 00000000..6b594dae --- /dev/null +++ b/app/controllers/code_ocean/errors_controller.rb @@ -0,0 +1,45 @@ +module CodeOcean + class ErrorsController < ApplicationController + before_action :set_execution_environment + + def authorize! + authorize(@error || @errors) + end + private :authorize! + + def create + @error = CodeOcean::Error.new(error_params) + authorize! + hint = Whistleblower.new(execution_environment: @error.execution_environment).generate_hint(@error.message) + respond_to do |format| + format.json do + if hint + render(json: {hint: hint}) + else + head (@error.save ? :created : :unprocessable_entity) + end + end + end + end + + def error_params + params[:error].permit(:message, :submission_id).merge(execution_environment_id: @execution_environment.id) if params[:error].present? + end + private :error_params + + def index + @errors = CodeOcean::Error.for_execution_environment(@execution_environment).grouped_by_message.paginate(page: params[:page]) + authorize! + end + + def set_execution_environment + @execution_environment = ExecutionEnvironment.find(params[:execution_environment_id]) + end + private :set_execution_environment + + def show + @error = CodeOcean::Error.find(params[:id]) + authorize! + end + end +end \ No newline at end of file diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb deleted file mode 100644 index 6a843eeb..00000000 --- a/app/controllers/errors_controller.rb +++ /dev/null @@ -1,43 +0,0 @@ -class ErrorsController < ApplicationController - before_action :set_execution_environment - - def authorize! - authorize(@error || @errors) - end - private :authorize! - - def create - @error = Error.new(error_params) - authorize! - hint = Whistleblower.new(execution_environment: @error.execution_environment).generate_hint(@error.message) - respond_to do |format| - format.json do - if hint - render(json: {hint: hint}) - else - head (@error.save ? :created : :unprocessable_entity) - end - end - end - end - - def error_params - params[:error].permit(:message, :submission_id).merge(execution_environment_id: @execution_environment.id) if params[:error].present? - end - private :error_params - - def index - @errors = Error.for_execution_environment(@execution_environment).grouped_by_message.paginate(page: params[:page]) - authorize! - end - - def set_execution_environment - @execution_environment = ExecutionEnvironment.find(params[:execution_environment_id]) - end - private :set_execution_environment - - def show - @error = Error.find(params[:id]) - authorize! - end -end diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 0e37dd07..8d16eb90 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -366,7 +366,7 @@ class SubmissionsController < ApplicationController end def store_error(stderr) - ::Error.create(submission_id: @submission.id, execution_environment_id: @submission.execution_environment.id, message: stderr) + CodeOcean::Error.create(submission_id: @submission.id, execution_environment_id: @submission.execution_environment.id, message: stderr) end private :store_error diff --git a/app/models/code_ocean/error.rb b/app/models/code_ocean/error.rb new file mode 100644 index 00000000..935962cf --- /dev/null +++ b/app/models/code_ocean/error.rb @@ -0,0 +1,19 @@ +module CodeOcean + class Error < ApplicationRecord + belongs_to :execution_environment + + scope :for_execution_environment, ->(execution_environment) { where(execution_environment_id: execution_environment.id) } + scope :grouped_by_message, -> { select('MAX(created_at) AS created_at, MAX(id) AS id, message, COUNT(id) AS count').group(:message).order('count DESC') } + + validates :execution_environment_id, presence: true + validates :message, presence: true + + def self.nested_resource? + true + end + + def to_s + id.to_s + end + end +end diff --git a/app/models/error.rb b/app/models/error.rb deleted file mode 100644 index 623e3558..00000000 --- a/app/models/error.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Error < ApplicationRecord - belongs_to :execution_environment - - scope :for_execution_environment, ->(execution_environment) { where(execution_environment_id: execution_environment.id) } - scope :grouped_by_message, -> { select('MAX(created_at) AS created_at, MAX(id) AS id, message, COUNT(id) AS count').group(:message).order('count DESC') } - - validates :execution_environment_id, presence: true - validates :message, presence: true - - def self.nested_resource? - true - end -end diff --git a/app/policies/code_ocean/error_policy.rb b/app/policies/code_ocean/error_policy.rb new file mode 100644 index 00000000..376af8d8 --- /dev/null +++ b/app/policies/code_ocean/error_policy.rb @@ -0,0 +1,7 @@ +module CodeOcean + class ErrorPolicy < AdminOrAuthorPolicy + def author? + @user == @record.execution_environment.author + end + end +end diff --git a/app/policies/error_policy.rb b/app/policies/error_policy.rb deleted file mode 100644 index 632f8b20..00000000 --- a/app/policies/error_policy.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ErrorPolicy < AdminOrAuthorPolicy - def author? - @user == @record.execution_environment.author - end -end diff --git a/app/views/application/_breadcrumbs.html.slim b/app/views/application/_breadcrumbs.html.slim index 216dcc7f..151e33e8 100644 --- a/app/views/application/_breadcrumbs.html.slim +++ b/app/views/application/_breadcrumbs.html.slim @@ -1,6 +1,6 @@ - if current_user.try(:internal_user?) ul.breadcrumb - - if model = Kernel.const_get(controller_name.classify) rescue nil + - if model = Kernel.const_get(controller_path.classify) rescue nil - object = model.find_by(id: params[:id]) - if model.try(:nested_resource?) li = model.model_name.human(count: 2) diff --git a/app/views/application/_navigation.html.slim b/app/views/application/_navigation.html.slim index 82c6271b..168a747f 100644 --- a/app/views/application/_navigation.html.slim +++ b/app/views/application/_navigation.html.slim @@ -10,7 +10,7 @@ li = link_to(t('breadcrumbs.statistics.show'), statistics_path) li.divider = render('navigation_submenu', title: t('activerecord.models.exercise.other'), - models: [Exercise, ExerciseCollection, ProxyExercise, Tag], link: exercises_path, cached: true) + models: [Exercise, ExerciseCollection, ProxyExercise, Tag, Submission], link: exercises_path, cached: true) = render('navigation_submenu', title: t('navigation.sections.users'), models: [InternalUser, ExternalUser], cached: true) = render('navigation_collection_link', model: ExecutionEnvironment, cached: true) diff --git a/app/views/errors/index.html.slim b/app/views/code_ocean/errors/index.html.slim similarity index 85% rename from app/views/errors/index.html.slim rename to app/views/code_ocean/errors/index.html.slim index 2db0d9de..dbfa2312 100644 --- a/app/views/errors/index.html.slim +++ b/app/views/code_ocean/errors/index.html.slim @@ -1,10 +1,10 @@ -h1 = ::Error.model_name.human(count: 2) +h1 = CodeOcean::Error.model_name.human(count: 2) .table-responsive table.table thead tr - th = t('.count') + th = t('errors.index.count') th = t('activerecord.attributes.error.message') th = t('shared.created_at') th = t('shared.actions') diff --git a/app/views/errors/show.html.slim b/app/views/code_ocean/errors/show.html.slim similarity index 77% rename from app/views/errors/show.html.slim rename to app/views/code_ocean/errors/show.html.slim index f5bf9a08..1bb6623e 100644 --- a/app/views/errors/show.html.slim +++ b/app/views/code_ocean/errors/show.html.slim @@ -1,4 +1,4 @@ -h1 = ::Error.model_name.human +h1 = CodeOcean::Error.model_name.human = row(label: 'error.message', value: @error.message) = row(label: 'shared.created_at', value: l(@error.created_at, format: :short)) diff --git a/app/views/shared/_edit_button.html.slim b/app/views/shared/_edit_button.html.slim index 1fc1870e..7ccd60f1 100644 --- a/app/views/shared/_edit_button.html.slim +++ b/app/views/shared/_edit_button.html.slim @@ -1 +1,3 @@ -= link_to(t('shared.edit'), local_assigns.fetch(:path, send(:"edit_#{object.class.name.underscore}_path", object)), class: 'btn btn-default pull-right') +// default value for fetch will always be evaluated even if it is not returned +- link_target = local_assigns.fetch(:path, false) || send(:"edit_#{object.class.name.underscore}_path", object) += link_to(t('shared.edit'), link_target, class: 'btn btn-default pull-right') diff --git a/app/views/shared/_new_button.html.slim b/app/views/shared/_new_button.html.slim index 3ed54d2b..9037487b 100644 --- a/app/views/shared/_new_button.html.slim +++ b/app/views/shared/_new_button.html.slim @@ -1,4 +1,6 @@ - if policy(model).new? - a.btn.btn-success href=local_assigns.fetch(:path, send(:"new_#{model.model_name.singular}_path")) + // default value for fetch will always be evaluated even if it is not returned + - href_target = local_assigns.fetch(:path, false) || send(:"new_#{model.model_name.singular}_path") + a.btn.btn-success href=href_target i.fa.fa-plus = t('shared.new_model', model: model.model_name.human) diff --git a/config/routes.rb b/config/routes.rb index 7c1f317b..b65d401e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,7 +28,7 @@ Rails.application.routes.draw do delete '/comment_by_id', to: 'comments#destroy_by_id' put '/comments', to: 'comments#update' - resources :subscriptions do + resources :subscriptions, only: [:create, :destroy] do member do get :unsubscribe, to: 'subscriptions#destroy' end @@ -40,8 +40,6 @@ Rails.application.routes.draw do get 'dashboard', to: 'dashboard#show' end - get '/help', to: 'application#help' - get 'statistics/', to: 'statistics#show' get 'statistics/graphs', to: 'statistics#graphs' get 'statistics/graphs/user-activity', to: 'statistics#user_activity' @@ -65,7 +63,7 @@ Rails.application.routes.draw do get :statistics end - resources :errors, only: [:create, :index, :show] + resources :errors, only: [:create, :index, :show], controller: 'code_ocean/errors' resources :hints end diff --git a/db/seeds/development.rb b/db/seeds/development.rb index 0aedc789..fab9a989 100644 --- a/db/seeds/development.rb +++ b/db/seeds/development.rb @@ -11,7 +11,7 @@ Rails.application.routes.default_url_options = Rails.application.config.action_m ExecutionEnvironment.create_factories # errors -Error.create_factories +CodeOcean::Error.create_factories # exercises @exercises = find_factories_by_class(Exercise).map(&:name).map { |factory_name| [factory_name, FactoryBot.create(factory_name)] }.to_h diff --git a/spec/factories/error.rb b/spec/factories/error.rb index 427fee7d..0bcae320 100644 --- a/spec/factories/error.rb +++ b/spec/factories/error.rb @@ -1,5 +1,5 @@ FactoryBot.define do - factory :error, class: Error do + factory :error, class: CodeOcean::Error do association :execution_environment, factory: :ruby message { "exercise.rb:4:in `
': undefined local variable or method `foo' for main:Object (NameError)" } end diff --git a/spec/models/error_spec.rb b/spec/models/error_spec.rb index 7f9f405a..aa111b3c 100644 --- a/spec/models/error_spec.rb +++ b/spec/models/error_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe Error do +describe CodeOcean::Error do let(:error) { described_class.create } it 'validates the presence of an execution environment' do