From 32c274d45529a20fb8066797a82d6c28921fe4ea Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 29 Nov 2017 10:39:05 +0100 Subject: [PATCH 01/14] Rename attribute and restructure conditions --- app/controllers/concerns/submission_scoring.rb | 2 +- app/controllers/submissions_controller.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb index 35de4ba5..f90b16ee 100644 --- a/app/controllers/concerns/submission_scoring.rb +++ b/app/controllers/concerns/submission_scoring.rb @@ -9,7 +9,7 @@ module SubmissionScoring assessment = assessor.assess(output) passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0)) testrun_output = passed ? nil : 'message: ' + output[:message].to_s + "\n stdout: " + output[:stdout].to_s + "\n stderr: " + output[:stderr].to_s - if !testrun_output.blank? + unless testrun_output.blank? submission.exercise.execution_environment.error_templates.each do |template| pattern = Regexp.new(template.signature).freeze if pattern.match(testrun_output) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 73db8c25..2fa518ec 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -203,11 +203,11 @@ class SubmissionsController < ApplicationController end def extract_errors - if !@message_buffer.blank? + unless @run_output.blank? @submission.exercise.execution_environment.error_templates.each do |template| pattern = Regexp.new(template.signature).freeze - if pattern.match(@message_buffer) - StructuredError.create_from_template(template, @message_buffer) + if pattern.match(@run_output) + StructuredError.create_from_template(template, @run_output) end end end From c62e9f53e5abfad9075b7753e5e3dcec51a25633 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 29 Nov 2017 16:06:45 +0100 Subject: [PATCH 02/14] fixed broken methodname (missing questionmark...) --- app/models/exercise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 06ed391f..f03d6641 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -364,7 +364,7 @@ class Exercise < ActiveRecord::Base end private :valid_main_file? - def needs_more_feedback + def needs_more_feedback? user_exercise_feedbacks.size <= MAX_EXERCISE_FEEDBACKS end From 53df8f9d92ddbf7a8dbdbac2438526b8ecb44408 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 29 Nov 2017 16:35:18 +0100 Subject: [PATCH 03/14] correct method call --- app/models/submission.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/submission.rb b/app/models/submission.rb index 38ea16d6..d75d6019 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -57,7 +57,7 @@ class Submission < ActiveRecord::Base end def redirect_to_feedback? - ((user_id + exercise.created_at.to_i) % 10 == 1) && exercise.needs_more_feedback + ((user_id + exercise.created_at.to_i) % 10 == 1) && exercise.needs_more_feedback? end def own_unsolved_rfc From 9234f11eaca82ee4109349343c8014e5e34b9a74 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Tue, 5 Dec 2017 10:57:11 +0100 Subject: [PATCH 04/14] remove failed option (it is not there yet) --- app/views/exercises/external_users/statistics.html.slim | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 8b5c3b30..06132754 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -54,8 +54,6 @@ h1 = "#{@exercise} (external user #{@external_user})" -submission_or_intervention.testruns.each do |run| - if run.passed .unit-test-result.positive-result title=run.output - - elsif run.failed - .unit-test-result.negative-result title=run.output - else .unit-test-result.unknown-result title=run.output td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0 From b25681a63efa6a1ec5c74f8e8c9157e0e422dbeb Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Tue, 12 Dec 2017 14:33:46 +0100 Subject: [PATCH 05/14] removed (partly outdated) xikolo-client that was used for name retrieval. --- lib/xikolo/client.rb | 59 --------------------------------------- lib/xikolo/user_client.rb | 15 ---------- 2 files changed, 74 deletions(-) delete mode 100644 lib/xikolo/client.rb delete mode 100644 lib/xikolo/user_client.rb diff --git a/lib/xikolo/client.rb b/lib/xikolo/client.rb deleted file mode 100644 index 4e6f22b2..00000000 --- a/lib/xikolo/client.rb +++ /dev/null @@ -1,59 +0,0 @@ -class Xikolo::Client - def self.get_user(user_id) - params = {:user_id => user_id} - response = get_request(user_profile_url(user_id), params) - if response - return JSON.parse(response) - else - return nil - end - end - - def self.user_profile_url(user_id) - return url + 'v2/users/' + user_id - end - - def self.post_request(url, params) - begin - return RestClient.post url, params, http_header - rescue - return nil - end - end - - def self.get_request(url, params) - begin - return RestClient.get url, {:params => params}.merge(http_header) - rescue - return nil - end - end - - def self.http_header - return {:accept => accept, :authorization => token} - end - - def self.url - @url ||= CodeOcean::Config.new(:code_ocean).read.fetch(:xikolo_api_url, 'http://localhost:3000/api/') #caches this with ||=, second value of fetch is default value - end - - def self.accept - 'application/vnd.xikolo.v1, application/vnd.api+json, application/json' - end - - def self.token - 'Token token='+Rails.application.secrets.openhpi_api_token#+'"' - end - - private - - def authenticate_with_user - params = {:email => "admin@openhpi.de", :password => "admin"} - response = post_request(authentication_url, params) - @token = 'Token token="'+JSON.parse(response)['token']+'"' - end - - def self.authentication_url - return @url + 'authenticate' - end -end \ No newline at end of file diff --git a/lib/xikolo/user_client.rb b/lib/xikolo/user_client.rb deleted file mode 100644 index c681c999..00000000 --- a/lib/xikolo/user_client.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Xikolo::UserClient - def self.get(user_id) - user = Xikolo::Client.get_user(user_id) - - # return default values if user is not found or if there is a server issue: - if user - name = user.dig('data', 'attributes', 'name') || "User " + user_id - user_visual = user.dig('data', 'attributes', 'avatar_url') || ActionController::Base.helpers.image_path('default.png') - language = user.dig('data', 'attributes', 'language') || "DE" - return {display_name: name, user_visual: user_visual, language: language} - else - return {display_name: "User " + user_id, user_visual: ActionController::Base.helpers.image_path('default.png'), language: "DE"} - end - end -end \ No newline at end of file From e934a29a45e759665b57b8f2a9f7616c4a12b7d1 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 20 Dec 2017 10:36:31 +0100 Subject: [PATCH 06/14] Set oscillating tests to pending --- spec/controllers/sessions_controller_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 480530da..81ec669f 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -132,12 +132,14 @@ describe SessionsController do end it 'redirects to recommended exercise if requested token of proxy exercise' do + pending 'test is currently oscillating' FactoryBot.create(:proxy_exercise, exercises: [exercise]) post :create_through_lti, custom_locale: locale, custom_token: ProxyExercise.first.token, oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: user.external_id expect(controller).to redirect_to(implement_exercise_path(exercise.id)) end it 'recommends only exercises who are 1 degree more complicated than what user has seen' do + pending 'test is currently oscillating' # dummy user has no exercises finished, therefore his highest difficulty is 0 FactoryBot.create(:proxy_exercise, exercises: [exercise, exercise2]) exercise.expected_difficulty = 3 From e51865c5619ea2e502339ff105baa817e7b55249 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Mon, 29 Jan 2018 16:18:40 +0100 Subject: [PATCH 07/14] Lint --- app/controllers/submissions_controller.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 2fa518ec..55eec4e6 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -216,7 +216,7 @@ class SubmissionsController < ApplicationController def handle_message(message, tubesock, container) @run_output ||= "" # Handle special commands first - if (/^#exit/.match(message)) + if /^#exit/.match(message) # Just call exit_container on the docker_client. # Do not call kill_socket for the websocket to the client here. # @docker_client.exit_container closes the socket to the container, @@ -228,17 +228,17 @@ class SubmissionsController < ApplicationController # Filter out information about run_command, test_command, user or working directory run_command = @submission.execution_environment.run_command % command_substitutions(params[:filename]) test_command = @submission.execution_environment.test_command % command_substitutions(params[:filename]) - if !(/root|workspace|#{run_command}|#{test_command}/.match(message)) + unless /root|workspace|#{run_command}|#{test_command}/.match(message) parse_message(message, 'stdout', tubesock) end end end def parse_message(message, output_stream, socket, recursive = true) - parsed = ''; + parsed = '' begin parsed = JSON.parse(message) - if(parsed.class == Hash && parsed.key?('cmd')) + if parsed.class == Hash and parsed.key?('cmd') socket.send_data message Rails.logger.info('parse_message sent: ' + message) else @@ -248,24 +248,24 @@ class SubmissionsController < ApplicationController end rescue JSON::ParserError => e # Check wether the message contains multiple lines, if true try to parse each line - if ((recursive == true) && (message.include? "\n")) + if recursive and message.include? "\n" for part in message.split("\n") self.parse_message(part,output_stream,socket,false) end - elsif(message.include? "")) + elsif @buffering and message.include? '/>' @buffer += message parsed = {'cmd'=>'write','stream'=>output_stream,'data'=>@buffer} socket.send_data JSON.dump(parsed) #socket.send_data @buffer @buffering = false #Rails.logger.info('Sent complete buffer') - elsif(@buffering) + elsif @buffering @buffer += message #Rails.logger.info('Appending to buffer') else @@ -281,7 +281,7 @@ class SubmissionsController < ApplicationController end def save_run_output - if !@run_output.blank? + unless @run_output.blank? @run_output = @run_output[(0..max_run_output_buffer_size-1)] # trim the string to max_message_buffer_size chars Testrun.create(file: @file, cause: 'run', submission: @submission, output: @run_output) end From f172f168db3e4390485c18cc377c4e8bba9978b3 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Tue, 30 Jan 2018 11:06:17 +0100 Subject: [PATCH 08/14] Refactor structured error attribute creation --- app/models/structured_error_attribute.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/models/structured_error_attribute.rb b/app/models/structured_error_attribute.rb index 6eb17fc4..65bda05e 100644 --- a/app/models/structured_error_attribute.rb +++ b/app/models/structured_error_attribute.rb @@ -3,15 +3,13 @@ class StructuredErrorAttribute < ActiveRecord::Base belongs_to :error_template_attribute def self.create_from_template(attribute, structured_error, message_buffer) - match = false value = nil result = message_buffer.match(attribute.regex) if result != nil - match = true if result.captures.size > 0 value = result.captures[0] end end - self.create(structured_error: structured_error, error_template_attribute: attribute, value: value, match: match) + self.create(structured_error: structured_error, error_template_attribute: attribute, value: value, match: result != nil) end end From 7768d342759450b73fefe7ca5d43f58af3a9f596 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Tue, 30 Jan 2018 11:08:00 +0100 Subject: [PATCH 09/14] Fix error detection in run output --- app/controllers/submissions_controller.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 55eec4e6..0b05f687 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -203,18 +203,19 @@ class SubmissionsController < ApplicationController end def extract_errors - unless @run_output.blank? + unless @raw_output.blank? @submission.exercise.execution_environment.error_templates.each do |template| pattern = Regexp.new(template.signature).freeze - if pattern.match(@run_output) - StructuredError.create_from_template(template, @run_output) + if pattern.match(@raw_output) + StructuredError.create_from_template(template, @raw_output) end end end end def handle_message(message, tubesock, container) - @run_output ||= "" + @raw_output ||= '' + @run_output ||= '' # Handle special commands first if /^#exit/.match(message) # Just call exit_container on the docker_client. @@ -275,6 +276,7 @@ class SubmissionsController < ApplicationController Rails.logger.info('parse_message sent: ' + JSON.dump(parsed)) end ensure + @raw_output += parsed['data'] if parsed.class == Hash and parsed.key? 'data' # save the data that was send to the run_output if there is enough space left. this will be persisted as a testrun with cause "run" @run_output += JSON.dump(parsed) if @run_output.size <= max_run_output_buffer_size end From 40fe5c4e69c595dc490974f5c24d643fab22b95b Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Tue, 30 Jan 2018 11:28:29 +0100 Subject: [PATCH 10/14] Save submission alongside structured error --- app/controllers/submissions_controller.rb | 22 +++++++++---------- app/models/structured_error.rb | 5 +++-- app/models/submission.rb | 1 + ...645_add_submission_to_structured_errors.rb | 5 +++++ db/schema.rb | 5 ++++- 5 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 db/migrate/20180130101645_add_submission_to_structured_errors.rb diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 0b05f687..3e24af1c 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -202,17 +202,6 @@ class SubmissionsController < ApplicationController tubesock.close end - def extract_errors - unless @raw_output.blank? - @submission.exercise.execution_environment.error_templates.each do |template| - pattern = Regexp.new(template.signature).freeze - if pattern.match(@raw_output) - StructuredError.create_from_template(template, @raw_output) - end - end - end - end - def handle_message(message, tubesock, container) @raw_output ||= '' @run_output ||= '' @@ -289,6 +278,17 @@ class SubmissionsController < ApplicationController end end + def extract_errors + unless @raw_output.blank? + @submission.exercise.execution_environment.error_templates.each do |template| + pattern = Regexp.new(template.signature).freeze + if pattern.match(@raw_output) + StructuredError.create_from_template(template, @raw_output, @submission) + end + end + end + end + def score hijack do |tubesock| Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive? diff --git a/app/models/structured_error.rb b/app/models/structured_error.rb index 2f03ec54..c1f6669c 100644 --- a/app/models/structured_error.rb +++ b/app/models/structured_error.rb @@ -1,9 +1,10 @@ class StructuredError < ActiveRecord::Base belongs_to :error_template + belongs_to :submission belongs_to :file, class_name: 'CodeOcean::File' - def self.create_from_template(template, message_buffer) - instance = self.create(error_template: template) + def self.create_from_template(template, message_buffer, submission) + instance = self.create(error_template: template, submission: submission) template.error_template_attributes.each do |attribute| StructuredErrorAttribute.create_from_template(attribute, instance, message_buffer) end diff --git a/app/models/submission.rb b/app/models/submission.rb index d75d6019..c27d01bd 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -8,6 +8,7 @@ class Submission < ActiveRecord::Base belongs_to :exercise has_many :testruns + has_many :structured_errors has_many :comments, through: :files delegate :execution_environment, to: :exercise diff --git a/db/migrate/20180130101645_add_submission_to_structured_errors.rb b/db/migrate/20180130101645_add_submission_to_structured_errors.rb new file mode 100644 index 00000000..3f7d2a5e --- /dev/null +++ b/db/migrate/20180130101645_add_submission_to_structured_errors.rb @@ -0,0 +1,5 @@ +class AddSubmissionToStructuredErrors < ActiveRecord::Migration + def change + add_reference :structured_errors, :submission, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 3ed07240..9ab33939 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171120153705) do +ActiveRecord::Schema.define(version: 20180130101645) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -305,8 +305,11 @@ ActiveRecord::Schema.define(version: 20171120153705) do t.integer "file_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "submission_id" end + add_index "structured_errors", ["submission_id"], name: "index_structured_errors_on_submission_id", using: :btree + create_table "submissions", force: :cascade do |t| t.integer "exercise_id" t.float "score" From efc271c4ed2d946eb85e7cbca376b1230305676c Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 31 Jan 2018 11:23:30 +0100 Subject: [PATCH 11/14] add column full_score_reached, fill it accordingly and show information in the rfc index --- app/controllers/concerns/submission_scoring.rb | 8 ++++++++ .../request_for_comments_controller.rb | 2 +- app/models/request_for_comment.rb | 2 +- app/views/request_for_comments/index.html.slim | 3 +++ ...reached_full_score_to_request_for_comment.rb | 15 +++++++++++++++ db/schema.rb | 17 +++++++++-------- 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb index 35de4ba5..7da26e8c 100644 --- a/app/controllers/concerns/submission_scoring.rb +++ b/app/controllers/concerns/submission_scoring.rb @@ -47,6 +47,14 @@ module SubmissionScoring end end submission.update(score: score) + if submission.normalized_score == 1.0 + Thread.new do + RequestForComment.where(exercise_id: submission.exercise_id, user_id: submission.user_id, user_type: submission.user_type).each{ |rfc| + rfc.full_score_reached = true + rfc.save + } + end + end outputs end end diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb index 4fd19a92..2f8219a9 100644 --- a/app/controllers/request_for_comments_controller.rb +++ b/app/controllers/request_for_comments_controller.rb @@ -20,7 +20,7 @@ class RequestForCommentsController < ApplicationController .group('request_for_comments.id, request_for_comments.user_id, request_for_comments.exercise_id, request_for_comments.file_id, request_for_comments.question, request_for_comments.created_at, request_for_comments.updated_at, request_for_comments.user_type, request_for_comments.solved, - request_for_comments.submission_id, request_for_comments.row_number') # ugly, but rails wants it this way + request_for_comments.full_score_reached, request_for_comments.submission_id, request_for_comments.row_number') # ugly, but rails wants it this way .select('request_for_comments.*, max(comments.updated_at) as last_comment') .search(params[:q]) @request_for_comments = @search.result.order('created_at DESC').paginate(page: params[:page], total_entries: @search.result.length) diff --git a/app/models/request_for_comment.rb b/app/models/request_for_comment.rb index 71a2fdd1..d0c300b6 100644 --- a/app/models/request_for_comment.rb +++ b/app/models/request_for_comment.rb @@ -52,6 +52,6 @@ class RequestForComment < ActiveRecord::Base private def self.row_number_user_sql - select("id, user_id, exercise_id, file_id, question, created_at, updated_at, user_type, solved, submission_id, row_number() OVER (PARTITION BY user_id ORDER BY created_at DESC) as row_number").to_sql + select("id, user_id, exercise_id, file_id, question, created_at, updated_at, user_type, solved, full_score_reached, submission_id, row_number() OVER (PARTITION BY user_id ORDER BY created_at DESC) as row_number").to_sql end end diff --git a/app/views/request_for_comments/index.html.slim b/app/views/request_for_comments/index.html.slim index a081dd55..585d518c 100644 --- a/app/views/request_for_comments/index.html.slim +++ b/app/views/request_for_comments/index.html.slim @@ -27,6 +27,9 @@ h1 = RequestForComment.model_name.human(count: 2) - if request_for_comment.solved? td span class="fa fa-check" aria-hidden="true" + - elsif request_for_comment.full_score_reached + td + span class="fa fa-check" style="color:darkgrey" aria-hidden="true" - else td = '' td = link_to(request_for_comment.exercise.title, request_for_comment) diff --git a/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb b/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb new file mode 100644 index 00000000..45a488b4 --- /dev/null +++ b/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb @@ -0,0 +1,15 @@ +class AddReachedFullScoreToRequestForComment < ActiveRecord::Migration + def up + add_column :request_for_comments, :full_score_reached, :boolean, default: false + RequestForComment.all.each { |rfc| + if (rfc.submission.exercise.has_user_solved(rfc.user)) + rfc.full_score_reached = true + rfc.save + end + } + end + + def down + remove_column :request_for_comments, :full_score_reached + end +end diff --git a/db/schema.rb b/db/schema.rb index 3ed07240..faeda040 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171120153705) do +ActiveRecord::Schema.define(version: 20180130172021) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -270,16 +270,17 @@ ActiveRecord::Schema.define(version: 20171120153705) do end create_table "request_for_comments", force: :cascade do |t| - t.integer "user_id", null: false - t.integer "exercise_id", null: false - t.integer "file_id", null: false + t.integer "user_id", null: false + t.integer "exercise_id", null: false + t.integer "file_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.string "user_type", limit: 255 + t.string "user_type", limit: 255 t.text "question" - t.boolean "solved", default: false + t.boolean "solved", default: false t.integer "submission_id" t.text "thank_you_note" + t.boolean "full_score_reached", default: false end create_table "searches", force: :cascade do |t| @@ -354,8 +355,8 @@ ActiveRecord::Schema.define(version: 20171120153705) do t.integer "working_time_seconds" t.string "feedback_text" t.integer "user_estimated_worktime" - t.datetime "created_at", default: '2017-11-20 18:20:25', null: false - t.datetime "updated_at", default: '2017-11-20 18:20:25', null: false + t.datetime "created_at", default: '2018-01-30 17:39:22', null: false + t.datetime "updated_at", default: '2018-01-30 17:39:22', null: false end create_table "user_exercise_interventions", force: :cascade do |t| From 65a6e390a54d1c1e2fdef3298c7bbc452cccb26f Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 31 Jan 2018 13:02:38 +0100 Subject: [PATCH 12/14] fix migration --- ...80130172021_add_reached_full_score_to_request_for_comment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb b/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb index 45a488b4..ed1d27a9 100644 --- a/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb +++ b/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb @@ -2,7 +2,7 @@ class AddReachedFullScoreToRequestForComment < ActiveRecord::Migration def up add_column :request_for_comments, :full_score_reached, :boolean, default: false RequestForComment.all.each { |rfc| - if (rfc.submission.exercise.has_user_solved(rfc.user)) + if (rfc.submission.present? && rfc.submission.exercise.has_user_solved(rfc.user)) rfc.full_score_reached = true rfc.save end From 6377c6ca0fa220a3d2f2dff88399455fb182c5bb Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 31 Jan 2018 13:06:18 +0100 Subject: [PATCH 13/14] Use skip instead of misused pending in oscillating tests --- spec/controllers/sessions_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 81ec669f..17bd0721 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -132,14 +132,14 @@ describe SessionsController do end it 'redirects to recommended exercise if requested token of proxy exercise' do - pending 'test is currently oscillating' + skip 'test is currently oscillating' FactoryBot.create(:proxy_exercise, exercises: [exercise]) post :create_through_lti, custom_locale: locale, custom_token: ProxyExercise.first.token, oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: user.external_id expect(controller).to redirect_to(implement_exercise_path(exercise.id)) end it 'recommends only exercises who are 1 degree more complicated than what user has seen' do - pending 'test is currently oscillating' + skip 'test is currently oscillating' # dummy user has no exercises finished, therefore his highest difficulty is 0 FactoryBot.create(:proxy_exercise, exercises: [exercise, exercise2]) exercise.expected_difficulty = 3 From da23cc22aa44c9eed18545b493ce646058e4e168 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 2 Feb 2018 14:38:28 +0100 Subject: [PATCH 14/14] add the required integer column and the increment statement when featured --- app/controllers/exercises_controller.rb | 3 +++ ...80202132034_add_times_featured_to_request_for_comments.rb | 5 +++++ db/schema.rb | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20180202132034_add_times_featured_to_request_for_comments.rb diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index fa48363e..7d4d2c43 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -416,6 +416,9 @@ class ExercisesController < ApplicationController flash[:notice] = I18n.t('exercises.submit.full_score_redirect_to_rfc') flash.keep(:notice) + # increase counter 'times_featured' in rfc + rfc.increment!(:times_featured) + respond_to do |format| format.html {redirect_to(rfc)} format.json {render(json: {redirect: url_for(rfc)})} diff --git a/db/migrate/20180202132034_add_times_featured_to_request_for_comments.rb b/db/migrate/20180202132034_add_times_featured_to_request_for_comments.rb new file mode 100644 index 00000000..348292af --- /dev/null +++ b/db/migrate/20180202132034_add_times_featured_to_request_for_comments.rb @@ -0,0 +1,5 @@ +class AddTimesFeaturedToRequestForComments < ActiveRecord::Migration + def change + add_column :request_for_comments, :times_featured, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 23b7e3a0..dc2f5022 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180130172021) do +ActiveRecord::Schema.define(version: 20180202132034) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -281,6 +281,7 @@ ActiveRecord::Schema.define(version: 20180130172021) do t.integer "submission_id" t.text "thank_you_note" t.boolean "full_score_reached", default: false + t.integer "times_featured", default: 0 end create_table "searches", force: :cascade do |t|