Fix error, submission, hints and help views
This commit is contained in:
@ -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
|
||||
|
45
app/controllers/code_ocean/errors_controller.rb
Normal file
45
app/controllers/code_ocean/errors_controller.rb
Normal file
@ -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
|
@ -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
|
@ -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
|
||||
|
||||
|
19
app/models/code_ocean/error.rb
Normal file
19
app/models/code_ocean/error.rb
Normal file
@ -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
|
@ -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
|
7
app/policies/code_ocean/error_policy.rb
Normal file
7
app/policies/code_ocean/error_policy.rb
Normal file
@ -0,0 +1,7 @@
|
||||
module CodeOcean
|
||||
class ErrorPolicy < AdminOrAuthorPolicy
|
||||
def author?
|
||||
@user == @record.execution_environment.author
|
||||
end
|
||||
end
|
||||
end
|
@ -1,5 +0,0 @@
|
||||
class ErrorPolicy < AdminOrAuthorPolicy
|
||||
def author?
|
||||
@user == @record.execution_environment.author
|
||||
end
|
||||
end
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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')
|
@ -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))
|
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 `<main>': undefined local variable or method `foo' for main:Object (NameError)" }
|
||||
end
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user