From efacb5a6a9c4c6e55a377bf1b8bedda2ab7b8c8b Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Tue, 27 Nov 2018 18:15:12 +0100 Subject: [PATCH] Completely remove old hints connected to the execution environment --- app/assets/javascripts/editor/editor.js.erb | 2 - app/assets/javascripts/editor/evaluation.js | 8 -- app/assets/stylesheets/editor.css.scss | 4 - .../code_ocean/errors_controller.rb | 7 +- app/controllers/hints_controller.rb | 57 ---------- app/controllers/submissions_controller.rb | 6 +- app/models/execution_environment.rb | 1 - app/models/hint.rb | 17 --- app/policies/hint_policy.rb | 5 - .../execution_environments/index.html.slim | 1 - app/views/exercises/_editor_output.html.slim | 5 - app/views/hints/_form.html.slim | 17 --- app/views/hints/edit.html.slim | 3 - app/views/hints/index.html.slim | 20 ---- app/views/hints/new.html.slim | 3 - app/views/hints/show.html.slim | 8 -- app/views/tags/index.html.slim | 3 +- config/routes.rb | 1 - db/migrate/20181127160857_drop_hints.rb | 5 + db/schema.rb | 12 +- db/seeds/development.rb | 3 - db/seeds/production.rb | 3 - lib/whistleblower.rb | 20 ---- spec/controllers/hints_controller_spec.rb | 103 ------------------ .../submissions_controller_spec.rb | 25 +---- spec/factories/hint.rb | 101 ----------------- spec/lib/whistleblower_spec.rb | 28 ----- spec/models/hint_spec.rb | 37 ------- spec/policies/hint_policy_spec.rb | 41 ------- 29 files changed, 12 insertions(+), 534 deletions(-) delete mode 100644 app/controllers/hints_controller.rb delete mode 100644 app/models/hint.rb delete mode 100644 app/policies/hint_policy.rb delete mode 100644 app/views/hints/_form.html.slim delete mode 100644 app/views/hints/edit.html.slim delete mode 100644 app/views/hints/index.html.slim delete mode 100644 app/views/hints/new.html.slim delete mode 100644 app/views/hints/show.html.slim create mode 100644 db/migrate/20181127160857_drop_hints.rb delete mode 100644 lib/whistleblower.rb delete mode 100644 spec/controllers/hints_controller_spec.rb delete mode 100644 spec/factories/hint.rb delete mode 100644 spec/lib/whistleblower_spec.rb delete mode 100644 spec/models/hint_spec.rb delete mode 100644 spec/policies/hint_policy_spec.rb diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb index 4e26723a..c4cb46f9 100644 --- a/app/assets/javascripts/editor/editor.js.erb +++ b/app/assets/javascripts/editor/editor.js.erb @@ -436,7 +436,6 @@ configureEditors: function () { url: $('#editor').data('errors-url') }); jqxhr.always(this.hideSpinner); - jqxhr.done(this.renderHint); }, toggleButtonStates: function () { @@ -482,7 +481,6 @@ configureEditors: function () { resetOutputTab: function () { this.clearOutput(); - $('#hint').fadeOut(); $('#flowrHint').fadeOut(); this.clearHints(); this.showOutputBar(); diff --git a/app/assets/javascripts/editor/evaluation.js b/app/assets/javascripts/editor/evaluation.js index 23e18bf0..ee912517 100644 --- a/app/assets/javascripts/editor/evaluation.js +++ b/app/assets/javascripts/editor/evaluation.js @@ -57,14 +57,6 @@ CodeOceanEditorEvaluation = { } }, - renderHint: function (object) { - var hint = object.data || object.hint; - if (hint) { - $('#hint .card-body').text(hint); - $('#hint').fadeIn(); - } - }, - renderScore: function () { var score = parseFloat($('#score').data('score')); var maximum_score = parseFloat($('#score').data('maximum-score')); diff --git a/app/assets/stylesheets/editor.css.scss b/app/assets/stylesheets/editor.css.scss index dff00f6f..63888039 100644 --- a/app/assets/stylesheets/editor.css.scss +++ b/app/assets/stylesheets/editor.css.scss @@ -64,10 +64,6 @@ button i.fa-spin { overflow: auto; } -#hint { - display: none; -} - #outputInformation { #output { max-height: 500px; diff --git a/app/controllers/code_ocean/errors_controller.rb b/app/controllers/code_ocean/errors_controller.rb index 6b594dae..632c354d 100644 --- a/app/controllers/code_ocean/errors_controller.rb +++ b/app/controllers/code_ocean/errors_controller.rb @@ -10,14 +10,9 @@ module CodeOcean 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 + head (@error.save ? :created : :unprocessable_entity) end end end diff --git a/app/controllers/hints_controller.rb b/app/controllers/hints_controller.rb deleted file mode 100644 index 48b86b63..00000000 --- a/app/controllers/hints_controller.rb +++ /dev/null @@ -1,57 +0,0 @@ -class HintsController < ApplicationController - include CommonBehavior - - before_action :set_execution_environment - before_action :set_hint, only: MEMBER_ACTIONS - - def authorize! - authorize(@hint || @hints) - end - private :authorize! - - def create - @hint = Hint.new(hint_params) - authorize! - create_and_respond(object: @hint, path: proc { execution_environment_hint_path(@execution_environment, @hint) }) - end - - def destroy - destroy_and_respond(object: @hint, path: execution_environment_hints_path(@execution_environment)) - end - - def edit - end - - def hint_params - params[:hint].permit(:locale, :message, :name, :regular_expression).merge(execution_environment_id: @execution_environment.id) if params[:hint].present? - end - private :hint_params - - def index - @hints = @execution_environment.hints.order(:name).paginate(page: params[:page]) - authorize! - end - - def new - @hint = Hint.new - authorize! - end - - def set_execution_environment - @execution_environment = ExecutionEnvironment.find(params[:execution_environment_id]) - end - private :set_execution_environment - - def set_hint - @hint = Hint.find(params[:id]) - authorize! - end - private :set_hint - - def show - end - - def update - update_and_respond(object: @hint, params: hint_params, path: execution_environment_hint_path(@execution_environment, @hint)) - end -end diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 32d1e560..0bf3ea07 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -128,11 +128,7 @@ class SubmissionsController < ApplicationController # server_sent_event.write({stderr: output[:stderr]}, event: 'output') if output[:stderr] # unless output[:stderr].nil? - # if hint = Whistleblower.new(execution_environment: @submission.execution_environment).generate_hint(output[:stderr]) - # server_sent_event.write(hint, event: 'hint') - # else - # store_error(output[:stderr]) - # end + # store_error(output[:stderr]) # end # end diff --git a/app/models/execution_environment.rb b/app/models/execution_environment.rb index 613fb082..33d57868 100644 --- a/app/models/execution_environment.rb +++ b/app/models/execution_environment.rb @@ -10,7 +10,6 @@ class ExecutionEnvironment < ApplicationRecord has_many :exercises belongs_to :file_type - has_many :hints has_many :error_templates scope :with_exercises, -> { where('id IN (SELECT execution_environment_id FROM exercises)') } diff --git a/app/models/hint.rb b/app/models/hint.rb deleted file mode 100644 index b54ba8a2..00000000 --- a/app/models/hint.rb +++ /dev/null @@ -1,17 +0,0 @@ -class Hint < ApplicationRecord - belongs_to :execution_environment - - validates :execution_environment_id, presence: true - validates :locale, presence: true - validates :message, presence: true - validates :name, presence: true - validates :regular_expression, presence: true - - def self.nested_resource? - true - end - - def to_s - name - end -end diff --git a/app/policies/hint_policy.rb b/app/policies/hint_policy.rb deleted file mode 100644 index 4c0a08fd..00000000 --- a/app/policies/hint_policy.rb +++ /dev/null @@ -1,5 +0,0 @@ -class HintPolicy < AdminOrAuthorPolicy - def author? - @user == @record.execution_environment.author - end -end diff --git a/app/views/execution_environments/index.html.slim b/app/views/execution_environments/index.html.slim index 20e99620..62fbd533 100644 --- a/app/views/execution_environments/index.html.slim +++ b/app/views/execution_environments/index.html.slim @@ -27,7 +27,6 @@ h1 = ExecutionEnvironment.model_name.human(count: 2) td = link_to(t('.shell'), shell_execution_environment_path(execution_environment)) td = link_to(t('shared.statistics'), statistics_execution_environment_path(execution_environment)) td = link_to(t('activerecord.models.error.other'), execution_environment_errors_path(execution_environment.id)) - td = link_to(t('activerecord.models.hint.other'), execution_environment_hints_path(execution_environment.id)) = render('shared/pagination', collection: @execution_environments) p = render('shared/new_button', model: ExecutionEnvironment) diff --git a/app/views/exercises/_editor_output.html.slim b/app/views/exercises/_editor_output.html.slim index 4568c313..46aa9665 100644 --- a/app/views/exercises/_editor_output.html.slim +++ b/app/views/exercises/_editor_output.html.slim @@ -38,11 +38,6 @@ div.h-100 id='output_sidebar_uncollapsed' class='d-none col-sm-12 enforce-bottom div.enforce-big-top-margin #turtlediv canvas#turtlecanvas.d-none width=400 height=400 - div.enforce-big-top-margin - #hint - .card.bg-warning.text-white - .card-header = t('exercises.implement.hint') - .card-body div.enforce-big-top-margin #prompt.input-group.d-none div.input-group-prepend diff --git a/app/views/hints/_form.html.slim b/app/views/hints/_form.html.slim deleted file mode 100644 index 21ab6bc1..00000000 --- a/app/views/hints/_form.html.slim +++ /dev/null @@ -1,17 +0,0 @@ -= form_for(@hint, url: execution_environment_hints_path(params[:execution_environment_id])) do |f| - = render('shared/form_errors', object: @hint) - .form-group - = f.label(:name) - = f.text_field(:name, class: 'form-control', required: true) - .form-group - = f.label(:locale) - = f.select(:locale, I18n.available_locales.map { |locale| [t("locales.#{locale}"), locale] }, {}, class: 'form-control') - .form-group - = f.label(:message) - = f.text_field(:message, class: 'form-control', placeholder: "'$2' has no method '$1'.", required: true) - .help-block.form-text = t('.hints.message') - .form-group - = f.label(:regular_expression) - = f.text_field(:regular_expression, class: 'form-control', placeholder: 'undefined method (\w+) for (\w+)', required: true) - .help-block.form-text = t('.hints.regular_expression') - .actions = render('shared/submit_button', f: f, object: @hint) diff --git a/app/views/hints/edit.html.slim b/app/views/hints/edit.html.slim deleted file mode 100644 index 0c1f4dac..00000000 --- a/app/views/hints/edit.html.slim +++ /dev/null @@ -1,3 +0,0 @@ -h1 = @hint - -= render('form') diff --git a/app/views/hints/index.html.slim b/app/views/hints/index.html.slim deleted file mode 100644 index 6a80bbdb..00000000 --- a/app/views/hints/index.html.slim +++ /dev/null @@ -1,20 +0,0 @@ -h1 = Hint.model_name.human(count: 2) - -.table-responsive - table.table - thead - tr - th = t('activerecord.attributes.hint.name') - th = t('activerecord.attributes.hint.locale') - th colspan=3 = t('shared.actions') - tbody - - @hints.each do |hint| - tr - td = hint.name - td = t("locales.#{hint.locale}") - td = link_to(t('shared.show'), execution_environment_hint_path(params[:execution_environment_id], hint.id)) - td = link_to(t('shared.edit'), edit_execution_environment_hint_path(params[:execution_environment_id], hint.id)) - td = link_to(t('shared.destroy'), execution_environment_hint_path(params[:execution_environment_id], hint.id), data: {confirm: t('shared.confirm_destroy')}, method: :delete) - -= render('shared/pagination', collection: @hints) -p = render('shared/new_button', model: Hint, path: new_execution_environment_hint_path(params[:execution_environment_id])) diff --git a/app/views/hints/new.html.slim b/app/views/hints/new.html.slim deleted file mode 100644 index a933bede..00000000 --- a/app/views/hints/new.html.slim +++ /dev/null @@ -1,3 +0,0 @@ -h1 = t('shared.new_model', model: Hint.model_name.human) - -= render('form') diff --git a/app/views/hints/show.html.slim b/app/views/hints/show.html.slim deleted file mode 100644 index 6db995f5..00000000 --- a/app/views/hints/show.html.slim +++ /dev/null @@ -1,8 +0,0 @@ -h1 - = @hint - = render('shared/edit_button', object: @hint, path: edit_execution_environment_hint_path(params[:execution_environment_id], @hint.id)) - -= row(label: 'hint.name', value: @hint.name) -= row(label: 'hint.locale', value: t("locales.#{@hint.locale}")) -= row(label: 'hint.message', value: @hint.message) -= row(label: 'hint.regular_expression', value: code_tag(@hint.regular_expression)) diff --git a/app/views/tags/index.html.slim b/app/views/tags/index.html.slim index 2d4916af..449a1165 100644 --- a/app/views/tags/index.html.slim +++ b/app/views/tags/index.html.slim @@ -5,8 +5,7 @@ h1 = Tag.model_name.human(count: 2) thead tr th = t('activerecord.attributes.hint.name') - /th = t('activerecord.attributes.hint.locale') - /th colspan=3 = t('shared.actions') + th colspan=3 = t('shared.actions') tbody - @tags.each do |tag| tr diff --git a/config/routes.rb b/config/routes.rb index b65d401e..e5c863fc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -64,7 +64,6 @@ Rails.application.routes.draw do end resources :errors, only: [:create, :index, :show], controller: 'code_ocean/errors' - resources :hints end post '/import_proforma_xml' => 'exercises#import_proforma_xml' diff --git a/db/migrate/20181127160857_drop_hints.rb b/db/migrate/20181127160857_drop_hints.rb new file mode 100644 index 00000000..83f0905e --- /dev/null +++ b/db/migrate/20181127160857_drop_hints.rb @@ -0,0 +1,5 @@ +class DropHints < ActiveRecord::Migration[5.2] + def change + drop_table :hints + end +end diff --git a/db/schema.rb b/db/schema.rb index f918e876..54d459df 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.define(version: 2018_11_26_163428) do +ActiveRecord::Schema.define(version: 2018_11_27_160857) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -223,16 +223,6 @@ ActiveRecord::Schema.define(version: 2018_11_26_163428) do t.index ["context_id", "context_type"], name: "index_files_on_context_id_and_context_type" end - create_table "hints", force: :cascade do |t| - t.integer "execution_environment_id" - t.string "locale", limit: 255 - t.text "message" - t.string "name", limit: 255 - t.string "regular_expression", limit: 255 - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "internal_users", force: :cascade do |t| t.integer "consumer_id" t.string "email", limit: 255 diff --git a/db/seeds/development.rb b/db/seeds/development.rb index fab9a989..845caeb9 100644 --- a/db/seeds/development.rb +++ b/db/seeds/development.rb @@ -19,8 +19,5 @@ CodeOcean::Error.create_factories # file types FileType.create_factories -# hints -Hint.create_factories - # submissions FactoryBot.create(:submission, exercise: @exercises[:fibonacci]) diff --git a/db/seeds/production.rb b/db/seeds/production.rb index 5b63f57b..ad12ee2c 100644 --- a/db/seeds/production.rb +++ b/db/seeds/production.rb @@ -25,9 +25,6 @@ Exercise.create_factories # file types FileType.create_factories -# hints -Hint.create_factories - # change all resources' author [ExecutionEnvironment, Exercise, FileType].each do |model| model.update_all(user_id: InternalUser.first.id) diff --git a/lib/whistleblower.rb b/lib/whistleblower.rb deleted file mode 100644 index 43876494..00000000 --- a/lib/whistleblower.rb +++ /dev/null @@ -1,20 +0,0 @@ -class Whistleblower - PLACEHOLDER_REGEXP = /\$(\d)/ - - def find_hint(stderr) - @execution_environment.hints.detect do |hint| - @matches = Regexp.new(hint.regular_expression).match(stderr) - end - end - private :find_hint - - def generate_hint(stderr) - if hint = find_hint(stderr) - hint.message.gsub(PLACEHOLDER_REGEXP) { @matches[Regexp.last_match(1).to_i] } - end - end - - def initialize(options = {}) - @execution_environment = options[:execution_environment] - end -end diff --git a/spec/controllers/hints_controller_spec.rb b/spec/controllers/hints_controller_spec.rb deleted file mode 100644 index d95b7efe..00000000 --- a/spec/controllers/hints_controller_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'rails_helper' - -describe HintsController do - let(:execution_environment) { FactoryBot.create(:ruby) } - let(:hint) { FactoryBot.create(:ruby_syntax_error) } - let(:user) { FactoryBot.create(:admin) } - before(:each) { allow(controller).to receive(:current_user).and_return(user) } - - describe 'POST #create' do - context 'with a valid hint' do - let(:perform_request) { proc { post :create, params: { execution_environment_id: execution_environment.id, hint: FactoryBot.attributes_for(:ruby_syntax_error) } } } - before(:each) { perform_request.call } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - - it 'creates the hint' do - expect { perform_request.call }.to change(Hint, :count).by(1) - end - - expect_redirect(Hint.last) - end - - context 'with an invalid hint' do - before(:each) { post :create, params: { execution_environment_id: execution_environment.id, hint: {} } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - expect_status(200) - expect_template(:new) - end - end - - describe 'DELETE #destroy' do - before(:each) { delete :destroy, params: { execution_environment_id: execution_environment.id, id: hint.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - - it 'destroys the hint' do - hint = FactoryBot.create(:ruby_syntax_error) - expect { delete :destroy, params: { execution_environment_id: execution_environment.id, id: hint.id } }.to change(Hint, :count).by(-1) - end - - expect_redirect { execution_environment_hints_path(execution_environment) } - end - - describe 'GET #edit' do - before(:each) { get :edit, params: { execution_environment_id: execution_environment.id, id: hint.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - expect_status(200) - expect_template(:edit) - end - - describe 'GET #index' do - before(:all) { FactoryBot.create_pair(:ruby_syntax_error) } - before(:each) { get :index, params: { execution_environment_id: execution_environment.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hints: Hint.all) - expect_status(200) - expect_template(:index) - end - - describe 'GET #new' do - before(:each) { get :new, params: { execution_environment_id: execution_environment.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - expect_status(200) - expect_template(:new) - end - - describe 'GET #show' do - before(:each) { get :show, params: { execution_environment_id: execution_environment.id, id: hint.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: :hint) - expect_status(200) - expect_template(:show) - end - - describe 'PUT #update' do - context 'with a valid hint' do - before(:each) { put :update, params: { execution_environment_id: execution_environment.id, hint: FactoryBot.attributes_for(:ruby_syntax_error), id: hint.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - expect_redirect { hint } - end - - context 'with an invalid hint' do - before(:each) { put :update, params: { execution_environment_id: execution_environment.id, hint: {name: ''}, id: hint.id } } - - expect_assigns(execution_environment: :execution_environment) - expect_assigns(hint: Hint) - expect_status(200) - expect_template(:edit) - end - end -end diff --git a/spec/controllers/submissions_controller_spec.rb b/spec/controllers/submissions_controller_spec.rb index 497318e0..9b2b1e98 100644 --- a/spec/controllers/submissions_controller_spec.rb +++ b/spec/controllers/submissions_controller_spec.rb @@ -167,28 +167,9 @@ describe SubmissionsController do after(:each) { perform_request } - context 'when the error is covered by a hint' do - let(:hint) { "Your object 'main' of class 'Object' does not understand the method 'foo'." } - - before(:each) do - expect_any_instance_of(Whistleblower).to receive(:generate_hint).with(stderr).and_return(hint) - end - - it 'does not store the error' do - pending("no server sent events used right now") - expect(CodeOcean::Error).not_to receive(:create) - end - end - - context 'when the error is not covered by a hint' do - before(:each) do - expect_any_instance_of(Whistleblower).to receive(:generate_hint).with(stderr) - end - - it 'stores the error' do - pending("no server sent events used right now") - expect(CodeOcean::Error).to receive(:create).with(execution_environment_id: submission.exercise.execution_environment_id, message: stderr) - end + it 'stores the error' do + pending("no server sent events used right now") + expect(CodeOcean::Error).to receive(:create).with(execution_environment_id: submission.exercise.execution_environment_id, message: stderr) end end end diff --git a/spec/factories/hint.rb b/spec/factories/hint.rb deleted file mode 100644 index ec1aba9d..00000000 --- a/spec/factories/hint.rb +++ /dev/null @@ -1,101 +0,0 @@ -FactoryBot.define do - factory :node_js_invalid_assignment, class: Hint do - association :execution_environment, factory: :node_js - english - message { 'There was an error with an assignment. Maybe you have to use the equality operator here.' } - name { 'Invalid assignment' } - regular_expression { 'Invalid left-hand side in assignment' } - end - - factory :node_js_reference_error, class: Hint do - association :execution_environment, factory: :node_js - english - message { "'$1' is not defined." } - name { 'ReferenceError' } - regular_expression { 'ReferenceError: (\w+) is not defined' } - end - - factory :node_js_syntax_error, class: Hint do - association :execution_environment, factory: :node_js - english - message { 'You seem to have made a typo.' } - name { 'SyntaxError' } - regular_expression { 'SyntaxError: Unexpected token (\w+)' } - end - - factory :ruby_load_error, class: Hint do - association :execution_environment, factory: :ruby - english - message { "The file '$1' cannot be found." } - name { 'LoadError' } - regular_expression { 'cannot load such file -- (\w+) (LoadError)' } - end - - factory :ruby_name_error_constant, class: Hint do - association :execution_environment, factory: :ruby - english - message { "The constant '$1' is not defined." } - name { 'NameError (uninitialized constant)' } - regular_expression { 'uninitialized constant (\w+) \(NameError\)' } - end - - factory :ruby_name_error_variable, class: Hint do - association :execution_environment, factory: :ruby - english - message { "Your object '$2' of class '$3' does not know what '$1' is. Maybe you made a typo or still have to define '$1'." } - name { 'NameError (undefined local variable or method)' } - regular_expression { 'undefined local variable or method `(\w+)\' for (\w+):(\w+) \(NameError\)' } - end - - factory :ruby_no_method_error, class: Hint do - association :execution_environment, factory: :ruby - english - message { "Your object '$2' of class '$3' does not understand the method '$1'. Maybe you made a typo or still have to implement that method." } - name { 'NoMethodError' } - regular_expression { 'undefined method `([\w\!\?=\[\]]+)\' for (\w+):(\w+) \(NoMethodError\)' } - end - - factory :ruby_syntax_error, class: Hint do - association :execution_environment, factory: :ruby - english - message { 'You seem to have made a typo.' } - name { 'SyntaxError' } - regular_expression { 'syntax error' } - end - - factory :ruby_system_stack_error, class: Hint do - association :execution_environment, factory: :ruby - english - message { 'You seem to have built an infinite loop or recursion.' } - name { 'SystemStackError' } - regular_expression { 'stack level too deep \(SystemStackError\)' } - end - - factory :sqlite_no_such_column, class: Hint do - association :execution_environment, factory: :sqlite - english - message { "The column '$1' does not exist." } - name { 'No Such Column' } - regular_expression { 'no such column: (\w+)' } - end - - factory :sqlite_no_such_table, class: Hint do - association :execution_environment, factory: :sqlite - english - message { "The table '$1' does not exist." } - name { 'No Such Table' } - regular_expression { 'no such table: (\w+)' } - end - - factory :sqlite_syntax_error, class: Hint do - association :execution_environment, factory: :sqlite - english - message { "You seem to have made a typo near '$1'." } - name { 'SyntaxError' } - regular_expression { 'near "(\w+)": syntax error' } - end - - trait :english do - locale { 'en' } - end -end diff --git a/spec/lib/whistleblower_spec.rb b/spec/lib/whistleblower_spec.rb deleted file mode 100644 index e0a8a8d9..00000000 --- a/spec/lib/whistleblower_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'rails_helper' - -describe Whistleblower do - let(:hint) { FactoryBot.create(:ruby_no_method_error) } - let(:stderr) { "undefined method `foo' for main:Object (NoMethodError)" } - let(:whistleblower) { described_class.new(execution_environment: hint.execution_environment) } - - describe '#find_hint' do - let(:find_hint) { whistleblower.send(:find_hint, stderr) } - - it 'finds the hint' do - expect(find_hint).to eq(hint) - end - - it 'stores the matches' do - find_hint - expect(whistleblower.instance_variable_get(:@matches)).to be_a(MatchData) - end - end - - describe '#generate_hint' do - it 'returns the customized hint message' do - message = whistleblower.generate_hint(stderr) - expect(message[0..9]).to eq(hint.message[0..9]) - expect(message[-10..-1]).to eq(hint.message[-10..-1]) - end - end -end diff --git a/spec/models/hint_spec.rb b/spec/models/hint_spec.rb deleted file mode 100644 index 87e04b51..00000000 --- a/spec/models/hint_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'rails_helper' - -describe Hint do - let(:hint) { described_class.create } - - it 'validates the presence of an execution environment' do - expect(hint.errors[:execution_environment_id]).to be_present - end - - it 'validates the presence of a locale' do - expect(hint.errors[:locale]).to be_present - end - - it 'validates the presence of a message' do - expect(hint.errors[:message]).to be_present - end - - it 'validates the presence of a name' do - expect(hint.errors[:name]).to be_present - end - - it 'validates the presence of a regular expression' do - expect(hint.errors[:regular_expression]).to be_present - end - - describe '.nested_resource?' do - it 'is true' do - expect(described_class.nested_resource?).to be true - end - end - - describe '#to_s' do - it "equals the hint's name" do - expect(hint.to_s).to eq(hint.name) - end - end -end diff --git a/spec/policies/hint_policy_spec.rb b/spec/policies/hint_policy_spec.rb deleted file mode 100644 index 2aa9d9e5..00000000 --- a/spec/policies/hint_policy_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'rails_helper' - -describe HintPolicy do - subject { described_class } - - let(:hint) { FactoryBot.build(:ruby_no_method_error) } - - [:create?, :index?, :new?].each do |action| - permissions(action) do - it 'grants access to admins' do - expect(subject).to permit(FactoryBot.build(:admin), hint) - end - - it 'grants access to teachers' do - expect(subject).to permit(FactoryBot.build(:teacher), hint) - end - - it 'does not grant access to external users' do - expect(subject).not_to permit(FactoryBot.build(:external_user), hint) - end - end - end - - [:destroy?, :edit?, :show?, :update?].each do |action| - permissions(action) do - it 'grants access to admins' do - expect(subject).to permit(FactoryBot.build(:admin), hint) - end - - it 'grants access to authors' do - expect(subject).to permit(hint.execution_environment.author, hint) - end - - it 'does not grant access to all other users' do - [:external_user, :teacher].each do |factory_name| - expect(subject).not_to permit(FactoryBot.build(factory_name), hint) - end - end - end - end -end