diff --git a/Gemfile.lock b/Gemfile.lock index 43820f9ea..07b02673b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -270,7 +270,6 @@ DEPENDENCIES newrelic_rpm paperclip (~> 4.3) pdfkit (~> 0.6.2) - paperclip (~> 4.3) pg (~> 0.17.0) pghero poltergeist (~> 1.5.0) diff --git a/app/controllers/assistants_controller.rb b/app/controllers/assistants_controller.rb index 71edbca1a..1575ff4e2 100644 --- a/app/controllers/assistants_controller.rb +++ b/app/controllers/assistants_controller.rb @@ -34,7 +34,7 @@ def destroy private def set_course - @course = Course.find_by id: params[:course_id] + @course = Course.find_by! name: params[:course_name] end def assistant_params diff --git a/app/controllers/breadcrumb_helpers.rb b/app/controllers/breadcrumb_helpers.rb index e048b201b..efbbe075e 100644 --- a/app/controllers/breadcrumb_helpers.rb +++ b/app/controllers/breadcrumb_helpers.rb @@ -14,9 +14,9 @@ def add_course_breadcrumb def add_exercise_breadcrumb if @exercise - add_breadcrumb "Exercise #{@exercise.name}", exercise_path(@exercise) + add_breadcrumb "Exercise #{@exercise.name}", organization_course_exercise_path(@organization, @course, @exercise) elsif @submission && @submission.exercise - add_breadcrumb "Exercise #{@submission.exercise.name}", exercise_path(@submission.exercise) + add_breadcrumb "Exercise #{@submission.exercise.name}", organization_course_exercise_path(@organization, @course, @submission.exercise) elsif @submission && @submission.exercise_name add_breadcrumb "(deleted exercise #{@submission.exercise_name}" else diff --git a/app/controllers/course_notifications_controller.rb b/app/controllers/course_notifications_controller.rb index 26671b679..fde61fc10 100644 --- a/app/controllers/course_notifications_controller.rb +++ b/app/controllers/course_notifications_controller.rb @@ -3,16 +3,16 @@ class CourseNotificationsController < ApplicationController before_action :set_organization def new - course = Course.find(course_notification_params[:course_id]) + course = Course.find_by!(name: course_notification_params[:course_name]) authorize! :send_mail_to_participants, course @notifier ||= CourseNotification.new - @course = Course.find_by(id: params[:course_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) add_course_breadcrumb add_breadcrumb 'Course notification' end def create - course = Course.find(course_notification_params[:course_id]) + course = Course.find_by!(name: course_notification_params[:course_name]) authorize! :send_mail_to_participants, course participants = User.course_students(course) @@ -48,10 +48,10 @@ def create private def course_notification_params - params.permit(:commit, :course_id, course_notification: [:topic, :message]) + params.permit(:commit, :course_name, course_notification: [:topic, :message]) end def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) end end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index b270b0de2..1a94bf781 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -60,7 +60,7 @@ def show # Method for teacher to give a single course for students to select. def show_json - course = [Course.find(params[:id])] + course = [Course.find_by!(name: params[:name])] authorize! :read, course return respond_access_denied('Authentication required') if current_user.guest? @@ -166,7 +166,7 @@ def save_deadlines end def help - @course = Course.find(params[:course_id]) + @course = Course.find_by!(name: params[:course_name]) authorize! :read, @course add_course_breadcrumb add_breadcrumb 'Help page' @@ -245,11 +245,12 @@ def assign_show_view_vars end def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) + @organization ||= Organization.find_by!(slug: params[:organization_id]) end def set_course - @course = Course.find(params[:id]) + @organization ||= Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:name], organization: @organization) end def group_params diff --git a/app/controllers/emails_controller.rb b/app/controllers/emails_controller.rb index 822ec1aed..8f92297f9 100644 --- a/app/controllers/emails_controller.rb +++ b/app/controllers/emails_controller.rb @@ -2,9 +2,9 @@ class EmailsController < ApplicationController def index organization_id = params[:organization_id] - course_id = params[:id] + course_name = params[:name] - if organization_id && course_id + if organization_id && course_name index_course else index_global @@ -26,8 +26,8 @@ def index_global end def index_course - @course = Course.find(params[:id]) - @organization = @course.organization + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:name], organization: @organization) authorize! :list_user_emails, @course diff --git a/app/controllers/exercise_status_controller.rb b/app/controllers/exercise_status_controller.rb index 9a7d989da..8013e47d5 100644 --- a/app/controllers/exercise_status_controller.rb +++ b/app/controllers/exercise_status_controller.rb @@ -2,10 +2,10 @@ class ExerciseStatusController < ApplicationController skip_authorization_check def show - course_id = params[:course_id] + course_name = params[:course_name] user_id = params[:id] - course = Course.where(id: course_id).first || Course.where(name: course_id).first + course = Course.where(id: course_name).first || Course.where(name: course_name).first user = User.where(id: user_id).first || User.where(login: user_id).first return respond_access_denied unless course.visible_to?(Guest.new) || current_user.administrator? diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 821b5dfaa..19bf894b2 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1,8 +1,7 @@ class ExercisesController < ApplicationController + before_action :set_params, only: [:show] + def show - @exercise = Exercise.find(params[:id]) - @course = Course.lock('FOR SHARE').find(@exercise.course_id) - @organization = @course.organization authorize! :read, @course authorize! :read, @exercise @@ -55,8 +54,8 @@ def show end def set_disabled_statuses - @course = Course.find(params[:course_id]) - @organization = @course.organization + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :teach, @organization selected_exercise_ids = params[:course][:exercises] @@ -71,4 +70,12 @@ def set_disabled_statuses redirect_to manage_exercises_organization_course_path(@organization, @course), notice: 'Exercises successfully updated.' end + + private + + def set_params + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.lock('FOR SHARE').find_by!(name: params[:course_name], organization: @organization) + @exercise = Exercise.find_by!(name: params[:name], course: @course) + end end diff --git a/app/controllers/feedback_answers_charts_controller.rb b/app/controllers/feedback_answers_charts_controller.rb index 397b5320e..efdb94090 100644 --- a/app/controllers/feedback_answers_charts_controller.rb +++ b/app/controllers/feedback_answers_charts_controller.rb @@ -1,7 +1,7 @@ class FeedbackAnswersChartsController < ApplicationController def show - @course = Course.find(params[:course_id]) - @organization = @course.organization + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :read_feedback_questions, @course authorize! :read_feedback_answers, @course diff --git a/app/controllers/feedback_answers_controller.rb b/app/controllers/feedback_answers_controller.rb index d3cb0b5e2..019308de8 100644 --- a/app/controllers/feedback_answers_controller.rb +++ b/app/controllers/feedback_answers_controller.rb @@ -1,15 +1,17 @@ class FeedbackAnswersController < ApplicationController def index - if params[:course_id] - @course = Course.find(params[:course_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) + + if params[:course_name] && !params[:exercise_name] + @course = Course.find_by!(name: params[:course_name], organization: @organization) @parent = @course @numeric_stats = @course.exercises.where(hidden: false).sort.map do |ex| [ex, FeedbackAnswer.numeric_answer_averages(ex), ex.submissions_having_feedback.count] end @title = @course.name - elsif params[:exercise_id] - @exercise = Exercise.find(params[:exercise_id]) - @course = @exercise.course + elsif params[:exercise_name] + @course = Course.find_by!(name: params[:course_name], organization: @organization) + @exercise = Exercise.find_by!(name: params[:exercise_name], course: @course) @parent = @exercise @numeric_stats = [[@exercise, FeedbackAnswer.numeric_answer_averages(@exercise), @exercise.submissions_having_feedback.count]] @title = @exercise.name @@ -17,11 +19,10 @@ def index return respond_not_found end - @organization = @course.organization add_course_breadcrumb if @exercise add_exercise_breadcrumb - add_breadcrumb 'Feedback', exercise_feedback_answers_path(@exercise) + add_breadcrumb 'Feedback', organization_course_exercise_feedback_answers_path(@organization, @course, @exercise) else add_breadcrumb 'Feedback', organization_course_feedback_answers_path end diff --git a/app/controllers/feedback_questions_controller.rb b/app/controllers/feedback_questions_controller.rb index b75994794..d54515b44 100644 --- a/app/controllers/feedback_questions_controller.rb +++ b/app/controllers/feedback_questions_controller.rb @@ -1,7 +1,6 @@ # Handles the feedback question editing UI. class FeedbackQuestionsController < ApplicationController - before_action :set_course - before_action :set_organization + before_action :set_params, only: [:index, :create, :new] def index add_course_breadcrumb @@ -85,8 +84,9 @@ def feedback_question_params params.permit({ feedback_question: [:question, :title, :kind] }, :intrange_min, :intrange_max, :commit, :course_id) end - def set_course - @course = Course.find(params[:course_id]) if params[:course_id] + def set_params + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) if params[:course_name] authorize! :read, @course end @@ -94,8 +94,4 @@ def fix_question_kind(question) return unless question.kind == 'intrange' question.kind += "[#{params[:intrange_min]}..#{params[:intrange_max]}]" end - - def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) - end end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index e640ea6dc..17efa6cca 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -119,8 +119,7 @@ def percent_completed_hash(courses, user) end def set_organization - @organization = Organization.find_by(slug: params[:id]) - fail ActiveRecord::RecordNotFound, 'Invalid organization id' if @organization.nil? + @organization = Organization.find_by!(slug: params[:id]) end def organization_params diff --git a/app/controllers/points_controller.rb b/app/controllers/points_controller.rb index c1c147c58..6a0a4c9dd 100644 --- a/app/controllers/points_controller.rb +++ b/app/controllers/points_controller.rb @@ -5,7 +5,7 @@ class PointsController < ApplicationController before_action :set_organization def index - @course = Course.find(params[:course_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :see_points, @course add_course_breadcrumb add_breadcrumb 'Points' @@ -27,13 +27,13 @@ def index def refresh_gdocs authorize! :refresh, @course @sheetname = params[:id] - @course = Course.find(params[:course_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) @notifications = @course.refresh_gdocs_worksheet @sheetname end def show @sheetname = params[:id] - @course = Course.find(params[:course_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :see_points, @course add_course_breadcrumb @@ -110,6 +110,6 @@ def sort_summary(summary, sorting) end def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) end end diff --git a/app/controllers/reviewed_submissions_controller.rb b/app/controllers/reviewed_submissions_controller.rb index 63f6a9dd9..0df101940 100644 --- a/app/controllers/reviewed_submissions_controller.rb +++ b/app/controllers/reviewed_submissions_controller.rb @@ -2,8 +2,8 @@ class ReviewedSubmissionsController < ApplicationController def index - @course = Course.find(params[:course_id]) - @organization = @course.organization + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :teach, @course add_course_breadcrumb add_breadcrumb 'Code reviews', organization_course_reviews_path(@organization, @course) diff --git a/app/controllers/reviews_controller.rb b/app/controllers/reviews_controller.rb index 12b6b36f3..ad9755e1b 100644 --- a/app/controllers/reviews_controller.rb +++ b/app/controllers/reviews_controller.rb @@ -5,9 +5,8 @@ class ReviewsController < ApplicationController before_action :set_organization, except: [:new, :create] def index - if params[:course_id] + if params[:course_name] fetch :course - @organization = @course.organization @my_reviews = @course.submissions .where(user_id: current_user.id) .where('requests_review OR requires_review OR reviewed') @@ -201,7 +200,7 @@ def mark_as_reviewed def fetch(*stuff) if stuff.include? :course - @course = Course.find(params[:course_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :read, @course end if stuff.include? :submission @@ -265,6 +264,6 @@ def award_points private def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) end end diff --git a/app/controllers/solutions_controller.rb b/app/controllers/solutions_controller.rb index eb6d0ab9c..7593c86a7 100644 --- a/app/controllers/solutions_controller.rb +++ b/app/controllers/solutions_controller.rb @@ -1,13 +1,13 @@ # Returns the suggestion solution as a ZIP. class SolutionsController < ApplicationController def show - @exercise = Exercise.find(params[:exercise_id]) - @course = @exercise.course - @organization = @course.organization + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) + @exercise = Exercise.find_by!(name: params[:exercise_name], course: @course) add_course_breadcrumb add_exercise_breadcrumb - add_breadcrumb 'Suggested solution' + add_breadcrumb 'Suggested solution', organization_course_exercise_solution_path(@organization, @course, @exercise) @solution = @exercise.solution begin diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index e79146704..3a26c2a0c 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -36,8 +36,8 @@ def show private def get_vars - if params[:course_id] - @course = Course.find(params[:course_id]) + if params[:course_name] + @course = Course.find_by!(name: params[:course_name], organization: @organization) end end @@ -168,6 +168,6 @@ def param_as_one_of(name, valid_values) private def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) end end diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 78fec2186..67e42d69e 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -4,12 +4,13 @@ # Also handles rerun requests. class SubmissionsController < ApplicationController around_action :course_transaction - before_action :get_course_and_exercise # Manually checked for #show and index skip_authorization_check only: [:show, :index] def index + set_course + respond_to do |format| format.json do if params[:row_format] == 'datatables' @@ -27,9 +28,12 @@ def index end def show - @course ||= @submission.course - @exercise ||= @submission.exercise - @organization = @course.organization + if params[:paste_key] + return unless set_paste + else + set_submission + end + add_course_breadcrumb add_exercise_breadcrumb add_submission_breadcrumb @@ -52,7 +56,7 @@ def show points: @submission.points_list, validations: @submission.validations, valgrind: @submission.valgrind, - solution_url: @exercise.solution.visible_to?(current_user) ? view_context.exercise_solution_url(@exercise) : nil, + solution_url: @exercise.solution.visible_to?(current_user) ? view_context.organization_course_exercise_solution_url(@organization, @course, @exercise) : nil, submitted_at: @submission.created_at, processing_time: @submission.processing_time, reviewed: @submission.reviewed?, @@ -95,6 +99,8 @@ def show end def create + set_exercise + if !params[:submission] || !params[:submission][:file] return respond_not_found('No ZIP file selected or failed to receive it') end @@ -148,7 +154,7 @@ def create redirect_to(submission_path(@submission), notice: 'Submission received.') else - redirect_to(exercise_path(@exercise), + redirect_to(organization_course_exercise_path(@organization, @course, @exercise), alert: errormsg) end end @@ -164,6 +170,8 @@ def create end def update + set_submission + submission = Submission.find(params[:id]) || respond_not_found authorize! :update, submission if params[:rerun] @@ -180,10 +188,12 @@ def update end def update_by_exercise + set_exercise(:name) + for submission in @exercise.submissions schedule_for_rerun(submission, -2) end - redirect_to exercise_path(@exercise), notice: 'Reruns scheduled' + redirect_to organization_course_exercise_path(@organization, @course, @exercise), notice: 'Reruns scheduled' end private @@ -194,31 +204,35 @@ def course_transaction end end - # Ugly manual access control :/ - def get_course_and_exercise - if params[:id] - @submission = Submission.find(params[:id]) - authorize! :read, @submission - @course = @submission.course - @exercise = @submission.exercise - elsif params[:exercise_id] - @exercise = Exercise.find(params[:exercise_id]) - @course = Course.lock('FOR SHARE').find(@exercise.course_id) - authorize! :read, @course - authorize! :read, @exercise - elsif params[:paste_key] - @submission = Submission.find_by_paste_key!(params[:paste_key]) - @exercise = @submission.exercise - @course = @exercise.course - @is_paste = true - check_access! - elsif params[:course_id] - @course = Course.lock('FOR SHARE').find(params[:course_id]) - @organization = @course.organization - authorize! :read, @course - else - respond_access_denied - end + def set_submission + @submission = Submission.find(params[:id]) + @exercise = @submission.exercise + @course = @submission.course + @organization = @course.organization + authorize! :read, @submission + end + + def set_exercise(param_name = :exercise_name) + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.lock('FOR SHARE').find_by!(name: params[:course_name], organization: @organization) + @exercise = Exercise.find_by!(name: params[param_name], course: @course) + authorize! :read, @course + authorize! :read, @exercise + end + + def set_course + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.lock('FOR SHARE').find_by!(name: params[:course_name], organization: @organization) + authorize! :read, @course + end + + def set_paste + @submission = Submission.find_by_paste_key!(params[:paste_key]) + @exercise = @submission.exercise + @course = @submission.course + @organization = @course.organization + @is_paste = true + check_access! end def schedule_for_rerun(submission, priority) @@ -266,13 +280,16 @@ def index_json_datatables def check_access! paste_visibility = @course.paste_visibility || 'open' + can_access = true case paste_visibility when 'protected' - respond_access_denied unless can?(:teach, @course) || @submission.user_id.to_s == current_user.id.to_s || (@submission.public? && @submission.exercise.completed_by?(current_user)) + can_access = false unless can?(:teach, @course) || @submission.user_id.to_s == current_user.id.to_s || (@submission.public? && @submission.exercise.completed_by?(current_user)) when 'no-tests-public' - respond_access_denied unless @submission.created_at > 2.hours.ago + can_access = false unless @submission.created_at > 2.hours.ago else - respond_access_denied unless can?(:teach, @course) || @submission.user_id.to_s == current_user.id.to_s || (@submission.public? && @submission.created_at > 2.hours.ago) + can_access = false unless can?(:teach, @course) || @submission.user_id.to_s == current_user.id.to_s || (@submission.public? && @submission.created_at > 2.hours.ago) end + respond_access_denied unless can_access + can_access end end diff --git a/app/controllers/teachers_controller.rb b/app/controllers/teachers_controller.rb index 929402077..23256839f 100644 --- a/app/controllers/teachers_controller.rb +++ b/app/controllers/teachers_controller.rb @@ -35,7 +35,7 @@ def destroy private def set_organization - @organization = Organization.find_by(slug: params[:organization_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) end def teacher_params diff --git a/app/controllers/unlocks_controller.rb b/app/controllers/unlocks_controller.rb index 34581eaae..f80c7f21b 100644 --- a/app/controllers/unlocks_controller.rb +++ b/app/controllers/unlocks_controller.rb @@ -1,9 +1,9 @@ # Receives explicit unlock requests and shows a web UI for making them. class UnlocksController < ApplicationController def show - @course = Course.find(params[:course_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :read, @course - @organization = Organization.find_by(slug: params[:organization_id]) @exercises = @course.unlockable_exercises_for(current_user) respond_to do |format| @@ -15,9 +15,9 @@ def show end def create - @course = Course.find(params[:course_id]) + @organization = Organization.find_by!(slug: params[:organization_id]) + @course = Course.find_by!(name: params[:course_name], organization: @organization) authorize! :read, @course - @organization = Organization.find_by(slug: params[:organization_id]) @exercises = @course.unlockable_exercises_for(current_user) Unlock.unlock_exercises(@exercises, current_user) diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index 50a5167c5..adee3c1ca 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -1,10 +1,10 @@ module ExercisesHelper def exercise_zip_url(e) - "#{exercise_url(e, format: 'zip')}" + "#{organization_course_exercise_url(e.course.organization, e.course, e, format: 'zip')}" end def exercise_solution_zip_url(e) - "#{exercise_solution_url(e, format: 'zip')}" + "#{organization_course_exercise_solution_url(e.course.organization, e.course, e, format: 'zip')}" end def green(percentage) diff --git a/app/helpers/submissions_helper.rb b/app/helpers/submissions_helper.rb index 4c0a69aa3..bb4460d6b 100644 --- a/app/helpers/submissions_helper.rb +++ b/app/helpers/submissions_helper.rb @@ -88,9 +88,12 @@ def submissions_for_datatables(submissions) end def link_to_submission_exericse(submission, text = nil, missing_text = '') - if submission.exercise - text = submission.exercise.name if text.nil? - link_to text, exercise_path(submission.exercise) + exercise = submission.exercise + if exercise + course = exercise.course + organization = course.organization + text = exercise.name if text.nil? + link_to text, organization_course_exercise_path(organization, course, exercise) else missing_text end diff --git a/app/models/course.rb b/app/models/course.rb index 1612f0f64..2b83f2edf 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -396,6 +396,10 @@ def contains_unlock_deadlines? exercise_groups.any? { |group| group.contains_unlock_deadlines?} end + def to_param + name + end + def material_url=(material) return super('') if material.blank? unless material =~ /^https?:\/\// diff --git a/app/models/exercise.rb b/app/models/exercise.rb index ec979650a..261c7f996 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -368,6 +368,10 @@ def self.count_completed(users, exercises) end end + def to_param + name + end + private def new_deadline_spec_obj(spec) diff --git a/app/views/courses/show.html.erb b/app/views/courses/show.html.erb index b8b77aa35..af8b96ebf 100644 --- a/app/views/courses/show.html.erb +++ b/app/views/courses/show.html.erb @@ -156,7 +156,7 @@ <% if signed_in? %> - + <% end %>

All exercises

diff --git a/app/views/exercises/_list_single.html.erb b/app/views/exercises/_list_single.html.erb index d5d7ff858..4fc8aba06 100644 --- a/app/views/exercises/_list_single.html.erb +++ b/app/views/exercises/_list_single.html.erb @@ -1,4 +1,4 @@ -<%= link_to exercise.name, exercise %> +<%= link_to exercise.name, organization_course_exercise_path(@organization, @course, exercise) %> <% notes = [] notes << 'hidden' if exercise.hidden? diff --git a/app/views/exercises/show.html.erb b/app/views/exercises/show.html.erb index 5fe6a722c..2b27da4d5 100644 --- a/app/views/exercises/show.html.erb +++ b/app/views/exercises/show.html.erb @@ -68,11 +68,11 @@ <% end %> <% if @exercise.solution && can?(:read, @exercise.solution) %> -
  • <%= link_to 'View suggested solution', exercise_solution_path(@exercise) %>
  • +
  • <%= link_to 'View suggested solution', organization_course_exercise_solution_path(@organization, @course, @exercise) %>
  • <% end %> <% if can? :read, FeedbackAnswer %> -
  • <%= link_to 'View feedback', exercise_feedback_answers_path(@exercise) %>
  • +
  • <%= link_to 'View feedback', organization_course_exercise_feedback_answers_path(@organization, @course, @exercise) %>
  • <% end %> @@ -110,7 +110,11 @@ end %>
    - <%= button_to 'Rerun all submissions', exercise_update_submissions_path(@exercise), :method => :put, :confirm => confirm_msg, class: "btn btn-danger"%> + <%= + button_to 'Rerun all submissions', + update_submissions_organization_course_exercise_path(@organization, @course, @exercise), + method: :put, confirm: confirm_msg, class: "btn btn-danger" + %> (may add points; never deletes points; may take a long time) diff --git a/app/views/feedback_answers/_numeric_feedback.html.erb b/app/views/feedback_answers/_numeric_feedback.html.erb index a6ce11634..1603c07e2 100644 --- a/app/views/feedback_answers/_numeric_feedback.html.erb +++ b/app/views/feedback_answers/_numeric_feedback.html.erb @@ -12,7 +12,7 @@ <% for exercise, averages, answer_count in stats %> <% if answer_count > 0 %> - <%= link_to exercise.name, exercise %> + <%= link_to exercise.name, organization_course_exercise_url(exercise.course.organization, exercise.course, exercise) %> <% for question in questions %> <%= if averages[question.id] then sprintf("%.2f", averages[question.id]) else '-' end %> <% end %> @@ -26,7 +26,7 @@ <% if parent.is_a?(Course) %> <% elsif parent.is_a?(Exercise) %> - + <% end %>
    diff --git a/app/views/feedback_answers/_text_feedback.html.erb b/app/views/feedback_answers/_text_feedback.html.erb index f4bc4d581..7d17d7323 100644 --- a/app/views/feedback_answers/_text_feedback.html.erb +++ b/app/views/feedback_answers/_text_feedback.html.erb @@ -9,7 +9,7 @@ <% end %> with <%= link_to "submission ##{answer.submission.id}", answer.submission %> <% unless @exercise %> - for <%= link_to answer.exercise.name, answer.exercise %> + for <%= link_to answer.exercise.name, organization_course_exercise_path(answer.exercise.course.organization, answer.exercise.course, answer.exercise) %> <% end %> at <%= answer.created_at.strftime("%H:%M %d.%m.%Y") %>
    diff --git a/app/views/submissions/_form.html.erb b/app/views/submissions/_form.html.erb index 52c7548cb..81af2e4f5 100644 --- a/app/views/submissions/_form.html.erb +++ b/app/views/submissions/_form.html.erb @@ -1,4 +1,4 @@ -<%= form_for(submission, :url => exercise_submissions_path(@exercise), :action => @form_action, +<%= form_for(submission, :url => organization_course_exercise_submissions_path(@organization, @course, @exercise), :action => @form_action, :html => {:multipart => true, class: "form-horizontal"} ) do |f| %> <%= render 'shared/error_messages', :target => submission %> diff --git a/app/views/submissions/_submission_details.html.erb b/app/views/submissions/_submission_details.html.erb index 322b3f9f1..07a31d690 100644 --- a/app/views/submissions/_submission_details.html.erb +++ b/app/views/submissions/_submission_details.html.erb @@ -51,7 +51,7 @@ <% end %> <% if can? :read, @exercise.solution %> -
  • <%= link_to 'View suggested solution', exercise_solution_path(@exercise) %>
  • +
  • <%= link_to 'View suggested solution', organization_course_exercise_solution_path(@organization, @course, @exercise) %>
  • <% end %> <% if can? :create_review, @course %> diff --git a/config/routes.rb b/config/routes.rb index 47adc71e9..a33379fec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,7 +15,7 @@ get 'course_templates', to: 'course_templates#list_for_teachers' - resources :courses do + resources :courses, param: :name do member do get 'refresh' post 'refresh' @@ -40,10 +40,18 @@ end end - resources :exercises, only: [:index] do + resources :exercises, param: :name, only: [:show] do collection do post 'set_disabled_statuses' end + + member do + put 'submissions' => 'submissions#update_by_exercise', :as => 'update_submissions' + end + + resources :submissions, only: [:create] + resource :solution, only: [:show] + resources :feedback_answers, only: [:index] end get 'help' @@ -104,12 +112,6 @@ get '/reset_password/:code' => 'password_reset_keys#show', :as => 'reset_password' delete '/reset_password/:code' => 'password_reset_keys#destroy' - resources :exercises, only: [:show] do - resources :submissions, only: [:create] - resource :solution, only: [:show] - resources :feedback_answers, only: [:index] - end - resources :submissions, only: [:show, :update] do resource :result, only: [:create] resources :feedback_answers, only: [:create] @@ -121,8 +123,6 @@ get 'paste/:paste_key', to: 'submissions#show', as: 'paste' resources :reviews, only: [:update, :destroy] - put '/exercises/:exercise_id/submissions' => 'submissions#update_by_exercise', :as => 'exercise_update_submissions' - resources :feedback_questions, only: [:show, :update, :destroy] do resource :position, only: [:update] end diff --git a/lib/course_info.rb b/lib/course_info.rb index 1c2453344..6d75e0275 100644 --- a/lib/course_info.rb +++ b/lib/course_info.rb @@ -59,7 +59,7 @@ def exercise_data(exercise) } data[:solution_zip_url] = @helpers.exercise_solution_zip_url(exercise) if @user.administrator? - data[:exercise_submissions_url] = @helpers.exercise_url(exercise, format: 'json', api_version: ApiVersion::API_VERSION) + data[:exercise_submissions_url] = @helpers.organization_course_exercise_url(exercise.course.organization, exercise.course, exercise, format: 'json', api_version: ApiVersion::API_VERSION) last_submission = get_latest_submission(exercise) data[:latest_submission_url] = @helpers.submission_url(last_submission, format: 'zip') unless last_submission.nil? data[:latest_submission_id] = last_submission.id unless last_submission.nil? @@ -70,7 +70,7 @@ def exercise_data(exercise) private def exercise_return_url(e) - "#{@helpers.exercise_submissions_url(e, format: 'json')}" + "#{@helpers.organization_course_exercise_submissions_url(e.course.organization, e.course, e, format: 'json')}" end def get_latest_submission(exercise) diff --git a/spec/controllers/assistants_controller_spec.rb b/spec/controllers/assistants_controller_spec.rb index ae5f99139..84d9009ad 100644 --- a/spec/controllers/assistants_controller_spec.rb +++ b/spec/controllers/assistants_controller_spec.rb @@ -20,7 +20,7 @@ user2 = FactoryGirl.create(:user) user3 = FactoryGirl.create(:user) @course.assistants << [user1, user2, user3] - get :index, organization_id: @organization.slug, course_id: @course.id + get :index, organization_id: @organization.slug, course_name: @course.name expect(assigns(:assistants)).to eq([user1, user2, user3]) end end @@ -28,20 +28,20 @@ describe 'POST create' do it 'with a valid username adds a new assistant' do expect do - post :create, organization_id: @organization.slug, course_id: @course.id, username: @user.username + post :create, organization_id: @organization.slug, course_name: @course.name, username: @user.username end.to change(Assistantship, :count).by(1) end it 'with a invalid username doesn\'t add any assistants' do expect do - post :create, organization_id: @organization.slug, course_id: @course.id, username: 'invalid' + post :create, organization_id: @organization.slug, course_name: @course.name, username: 'invalid' end.to change(Assistantship, :count).by(0) end it 'with a username that already is an assistant for course, donesn\'t add' do Assistantship.create! user: @user, course: @course expect do - post :create, organization_id: @organization.slug, course_id: @course.id, username: @user.username + post :create, organization_id: @organization.slug, course_name: @course.name, username: @user.username end.to change(Assistantship, :count).by(0) end end @@ -50,7 +50,7 @@ it 'removes assistant' do @assistantship = Assistantship.create! user: @user, course: @course expect do - delete :destroy, organization_id: @organization.slug, course_id: @course.id, id: @assistantship.to_param + delete :destroy, organization_id: @organization.slug, course_name: @course.name, id: @assistantship.to_param end.to change(Assistantship, :count).by(-1) end end @@ -63,14 +63,14 @@ describe 'GET index' do it 'denies access' do - get :index, organization_id: @organization.slug, course_id: @course.id + get :index, organization_id: @organization.slug, course_name: @course.name expect(response.code.to_i).to eq(401) end end describe 'POST create' do it 'denies access' do - post :create, organization_id: @organization.slug, course_id: @course.id, username: @user.username + post :create, organization_id: @organization.slug, course_name: @course.name, username: @user.username expect(response.code.to_i).to eq(401) end end @@ -78,7 +78,7 @@ describe 'DELETE destroy' do it 'denies access' do @assistantship = Assistantship.create! user: @user, course: @course - delete :destroy, organization_id: @organization.slug, course_id: @course, id: @assistantship.to_param + delete :destroy, organization_id: @organization.slug, course_name: @course.name, id: @assistantship.to_param expect(response.code.to_i).to eq(401) end end diff --git a/spec/controllers/course_notifications_controller_spec.rb b/spec/controllers/course_notifications_controller_spec.rb index f3b6c590d..d9e86f398 100644 --- a/spec/controllers/course_notifications_controller_spec.rb +++ b/spec/controllers/course_notifications_controller_spec.rb @@ -16,7 +16,7 @@ message: message }, organization_id: @organization.slug, - course_id: @course.id + course_name: @course.name } end diff --git a/spec/controllers/courses_controller_spec.rb b/spec/controllers/courses_controller_spec.rb index b2da4ddda..f711a4716 100644 --- a/spec/controllers/courses_controller_spec.rb +++ b/spec/controllers/courses_controller_spec.rb @@ -50,7 +50,8 @@ def get_index_json(options = {}) describe 'GET show' do before :each do - @course = FactoryGirl.create(:course) + @course = FactoryGirl.create(:course, organization: @organization) + @exercise = FactoryGirl.create(:exercise, course: @course) end describe 'for administrators' do @@ -61,10 +62,10 @@ def get_index_json(options = {}) it "should show everyone's submissions" do user1 = FactoryGirl.create(:user) user2 = FactoryGirl.create(:user) - sub1 = FactoryGirl.create(:submission, user: user1, course: @course) - sub2 = FactoryGirl.create(:submission, user: user2, course: @course) + sub1 = FactoryGirl.create(:submission, user: user1, course: @course, exercise: @exercise) + sub2 = FactoryGirl.create(:submission, user: user2, course: @course, exercise: @exercise) - get :show, organization_id: @organization.slug, id: @course.id + get :show, organization_id: @organization.slug, name: @course.name expect(assigns['submissions']).to include(sub1) expect(assigns['submissions']).to include(sub2) @@ -80,7 +81,7 @@ def get_index_json(options = {}) FactoryGirl.create(:submission, course: @course) FactoryGirl.create(:submission, course: @course) - get :show, organization_id: @organization.slug, id: @course.id + get :show, organization_id: @organization.slug, name: @course.name expect(assigns['submissions']).to be_nil end @@ -95,7 +96,7 @@ def get_index_json(options = {}) my_sub = FactoryGirl.create(:submission, user: @user, course: @course) other_guys_sub = FactoryGirl.create(:submission, user: other_user, course: @course) - get :show, organization_id: @organization.slug, id: @course.id + get :show, organization_id: @organization.slug, name: @course.name expect(assigns['submissions']).to include(my_sub) expect(assigns['submissions']).not_to include(other_guys_sub) @@ -104,7 +105,7 @@ def get_index_json(options = {}) describe 'in JSON format' do before :each do - @course = FactoryGirl.create(:course, name: 'Course1') + @course = FactoryGirl.create(:course, name: 'Course1', organization: @organization) @course.exercises << FactoryGirl.create(:returnable_exercise, name: 'Exercise1', course: @course) @course.exercises << FactoryGirl.create(:returnable_exercise, name: 'Exercise2', course: @course) @course.exercises << FactoryGirl.create(:returnable_exercise, name: 'Exercise3', course: @course) @@ -114,7 +115,7 @@ def get_show_json(options = {}, parse_json = true) options = { format: 'json', api_version: ApiVersion::API_VERSION, - id: @course.id.to_s, + name: @course.name, organization_id: @organization.slug }.merge options @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, @user.password) @@ -129,11 +130,13 @@ def get_show_json(options = {}, parse_json = true) it 'should render the exercises for each course' do result = get_show_json + ex = @course.exercises[0]; + exs = result['course']['exercises'] expect(exs[0]['name']).to eq('Exercise1') expect(exs[1]['name']).to eq('Exercise2') - expect(exs[0]['zip_url']).to eq(exercise_url(@course.exercises[0].id, format: 'zip')) - expect(exs[0]['return_url']).to eq(exercise_submissions_url(@course.exercises[0].id, format: 'json')) + expect(exs[0]['zip_url']).to eq(organization_course_exercise_url(ex.course.organization, ex.course, ex, format: 'zip')) + expect(exs[0]['return_url']).to eq(organization_course_exercise_submissions_url(ex.course.organization, ex.course, ex, format: 'json')) end it 'should include only visible exercises' do @@ -281,7 +284,7 @@ def get_show_json(options = {}, parse_json = true) it 'can\'t refresh if course created from template' do @course = FactoryGirl.create :course, organization: @organization, course_template: @template, source_url: @template.source_url - post :refresh, organization_id: @organization.slug, id: @course.id + post :refresh, organization_id: @organization.slug, name: @course.name expect(response.code.to_i).to eq(401) end end @@ -303,7 +306,7 @@ def get_show_json(options = {}, parse_json = true) describe 'with valid parameters' do before :each do Teachership.create user: @user, organization: @organization - put :update, organization_id: @organization.to_param, id: @course.to_param, course: { + put :update, organization_id: @organization.to_param, name: @course.to_param, course: { title: 'newTitle', description: 'newDescription', material_url: 'http://newMaterial.com', @@ -327,21 +330,21 @@ def get_show_json(options = {}, parse_json = true) describe 'with invalid parameters' do it 're-renders course update form' do Teachership.create user: @user, organization: @organization - put :update, organization_id: @organization.to_param, id: @course.to_param, course: {title: 'a' * 41} + put :update, organization_id: @organization.to_param, name: @course.to_param, course: {title: 'a' * 41} expect(response).to render_template('edit') end end it 'can\'t update course name' do Teachership.create user: @user, organization: @organization - put :update, organization_id: @organization.to_param, id: @course.to_param, course: {name: 'newName'} + put :update, organization_id: @organization.to_param, name: @course.to_param, course: {name: 'newName'} expect(Course.last.name).to eq('oldName') end it 'can\'t update course template id' do Teachership.create user: @user, organization: @organization old_id = @course.course_template_id - put :update, organization_id: @organization.to_param, id: @course.to_param, course: {course_template_id: 2} + put :update, organization_id: @organization.to_param, name: @course.to_param, course: {course_template_id: 2} expect(Course.last.course_template_id).to eq(old_id) end @@ -355,19 +358,19 @@ def get_show_json(options = {}, parse_json = true) end it 'can\'t update source_url' do - put :update, organization_id: @organization.to_param, id: @course.to_param, course: {source_url: @new_repo_path} + put :update, organization_id: @organization.to_param, name: @course.to_param, course: {source_url: @new_repo_path} expect(Course.last.source_url).to eq(@template.source_url) end it 'can\'t update git_branch' do - put :update, organization_id: @organization.to_param, id: @course.to_param, course: {git_branch: 'ufobranch'} + put :update, organization_id: @organization.to_param, name: @course.to_param, course: {git_branch: 'ufobranch'} expect(Course.last.git_branch).to eq('master') end end describe 'when non-teacher attemps to update' do before :each do - put :update, organization_id: @organization.to_param, id: @course.to_param, course: {title: 'newTitle', description: 'newDescription', material_url: 'http://newMaterial.com'} + put :update, organization_id: @organization.to_param, name: @course.to_param, course: {title: 'newTitle', description: 'newDescription', material_url: 'http://newMaterial.com'} end it 'should respond with 401' do @@ -385,13 +388,13 @@ def get_show_json(options = {}, parse_json = true) describe 'POST disable' do before :each do - @course = FactoryGirl.create(:course) + @course = FactoryGirl.create(:course, organization: @organization) end describe 'As a teacher' do it 'disables the course' do controller.current_user = @teacher - post :disable, organization_id: @organization.slug, id: @course.id.to_s + post :disable, organization_id: @organization.slug, name: @course.name expect(Course.find(@course.id).disabled?).to eq(true) end end @@ -399,7 +402,7 @@ def get_show_json(options = {}, parse_json = true) describe 'As a student' do it 'denies access' do controller.current_user = @user - post :disable, organization_id: @organization.slug, id: @course.id.to_s + post :disable, organization_id: @organization.slug, name: @course.name expect(response.code.to_i).to eq(401) end end @@ -407,13 +410,13 @@ def get_show_json(options = {}, parse_json = true) describe 'POST enable' do before :each do - @course = FactoryGirl.create(:course) + @course = FactoryGirl.create(:course, organization: @organization) end describe 'As a teacher' do it 'enables the course' do controller.current_user = @teacher - post :enable, organization_id: @organization.slug, id: @course.id.to_s + post :enable, organization_id: @organization.slug, name: @course.name expect(Course.find(@course.id).disabled?).to eq(false) end end @@ -421,7 +424,7 @@ def get_show_json(options = {}, parse_json = true) describe 'As a student' do it 'denies access' do controller.current_user = @user - post :disable, organization_id: @organization.slug, id: @course.id.to_s + post :disable, organization_id: @organization.slug, name: @course.name expect(response.code.to_i).to eq(401) end end @@ -441,7 +444,7 @@ def get_show_json(options = {}, parse_json = true) post :save_deadlines, organization_id: @organization.slug, - id: @course.id, + name: @course.name, empty_group: { soft: { static: '1.1.2000', unlock: '' }, hard: { static: '', unlock: 'unlock + 2 weeks' } @@ -464,7 +467,7 @@ def get_show_json(options = {}, parse_json = true) post :save_deadlines, organization_id: @organization.slug, - id: @course.id, + name: @course.name, group: { group1: { soft: { static: '1.1.2000', unlock: 'unlock + 7 days' }, @@ -494,10 +497,9 @@ def get_show_json(options = {}, parse_json = true) describe 'GET manage_unlocks' do it 'when non-teacher should respond with a 401' do - @course = FactoryGirl.create :course - @course.organization = @organization + @course = FactoryGirl.create :course, organization: @organization controller.current_user = @user - get :manage_unlocks, organization_id: @organization.slug, id: @course.id + get :manage_unlocks, organization_id: @organization.slug, name: @course.name expect(response.code.to_i).to eq(401) end end @@ -518,7 +520,7 @@ def get_show_json(options = {}, parse_json = true) @course.exercises.create(name: 'e2') @course.exercises.create(name: 'e3') - post :save_unlocks, organization_id: @organization.slug, id: @course.id, empty_group: { '0' => '1.2.2000' } + post :save_unlocks, organization_id: @organization.slug, name: @course.name, empty_group: { '0' => '1.2.2000' } @course.exercise_group_by_name('').exercises(false).each do |e| expect(e.unlock_spec_obj.valid_after).to be_within(1.day).of Time.new(2000, 2, 1) @@ -531,7 +533,7 @@ def get_show_json(options = {}, parse_json = true) @course.exercises.create(name: 'group1-e3') @course.exercises.create(name: 'group2-e1') - post :save_unlocks, organization_id: @organization.slug, id: @course.id, group: { group1: { '0' => '1.2.2000' } } + post :save_unlocks, organization_id: @organization.slug, name: @course.name, group: { group1: { '0' => '1.2.2000' } } @course.exercise_group_by_name('group1').exercises(false).each do |e| expect(e.unlock_spec_obj.valid_after).to be_within(1.day).of Time.new(2000, 2, 1) @@ -546,8 +548,8 @@ def get_show_json(options = {}, parse_json = true) @course.exercises.create(name: 'e2') @course.exercises.create(name: 'e3') - post :save_unlocks, organization_id: @organization.slug, id: @course.id, empty_group: { 0 => '1.2.2000' } - post :save_unlocks, organization_id: @organization.slug, id: @course.id, empty_group: { 0 => '' } + post :save_unlocks, organization_id: @organization.slug, name: @course.name, empty_group: { 0 => '1.2.2000' } + post :save_unlocks, organization_id: @organization.slug, name: @course.name, empty_group: { 0 => '' } @course.exercise_group_by_name('').exercises(false).each do |e| expect(e.unlock_spec_obj.valid_after).to be_nil @@ -559,7 +561,7 @@ def get_show_json(options = {}, parse_json = true) @course.exercises.create(name: 'e2') @course.exercises.create(name: 'e3') - post :save_unlocks, organization_id: @organization.slug, id: @course.id, + post :save_unlocks, organization_id: @organization.slug, name: @course.name, empty_group: { '0' => '1.2.2000', '1' => 'exercise e1', '2' => '5% of e2' } @course.exercise_group_by_name('').exercises(false).each do |e| @@ -573,7 +575,7 @@ def get_show_json(options = {}, parse_json = true) it 'when non-teacher should respond with a 401' do @course.exercises.create(name: 'e') - post :save_unlocks, organization_id: @organization.slug, id: @course.id, empty_group: { 0 => '1.2.2000' } + post :save_unlocks, organization_id: @organization.slug, name: @course.name, empty_group: { 0 => '1.2.2000' } expect(response.code.to_i).to eq(401) end end @@ -586,7 +588,7 @@ def get_show_json(options = {}, parse_json = true) describe 'when teacher' do it 'toggles visibility of submsission results' do controller.current_user = @teacher - post :toggle_submission_result_visibility, organization_id: @organization.slug, id: @course.id + post :toggle_submission_result_visibility, organization_id: @organization.slug, name: @course.name @course.reload expect(@course.hide_submission_results).to be true expect(response).to redirect_to(organization_course_path) @@ -597,7 +599,7 @@ def get_show_json(options = {}, parse_json = true) it 'toggles visibility of submsission results' do Assistantship.create(user: @user, course: @course) controller.current_user = @user - post :toggle_submission_result_visibility, organization_id: @organization.slug, id: @course.id + post :toggle_submission_result_visibility, organization_id: @organization.slug, name: @course.name @course.reload expect(@course.hide_submission_results).to be true expect(response).to redirect_to(organization_course_path) @@ -607,7 +609,7 @@ def get_show_json(options = {}, parse_json = true) describe 'when non-teacher or non-admin' do it 'acces denied' do controller.current_user = @user - post :toggle_submission_result_visibility, organization_id: @organization.slug, id: @course.id + post :toggle_submission_result_visibility, organization_id: @organization.slug, name: @course.name @course.reload expect(response.code.to_i).to eq(401) end diff --git a/spec/controllers/emails_controller_spec.rb b/spec/controllers/emails_controller_spec.rb index 8a9f34bd2..c111c955c 100644 --- a/spec/controllers/emails_controller_spec.rb +++ b/spec/controllers/emails_controller_spec.rb @@ -47,7 +47,7 @@ it 'assigns users in @students array if they have submitted exercises to the course if current user is teacher' do controller.current_user = @teacher - get :index, organization_id: @organization.slug, id: @course.id + get :index, organization_id: @organization.slug, name: @course.name expect(assigns(:students)).to include(@user1) expect(assigns(:students)).to include(@user2) expect(assigns(:students)).to_not include(@user3) @@ -55,7 +55,7 @@ it 'denies access for non-teachers' do controller.current_user = @user - get :index, organization_id: @organization.slug, id: @course.id + get :index, organization_id: @organization.slug, name: @course.name expect(response.code.to_i).to eq(401) end end diff --git a/spec/controllers/exercise_status_controller_spec.rb b/spec/controllers/exercise_status_controller_spec.rb index 97c083589..eb5a55312 100644 --- a/spec/controllers/exercise_status_controller_spec.rb +++ b/spec/controllers/exercise_status_controller_spec.rb @@ -3,8 +3,7 @@ describe ExerciseStatusController, type: :controller do before :each do @organization = FactoryGirl.create(:accepted_organization) - @course = FactoryGirl.create(:course) - @course.organization = @organization + @course = FactoryGirl.create(:course, organization: @organization) @exercise = FactoryGirl.create(:exercise, course: @course) @exercise2 = FactoryGirl.create(:exercise, course: @course) @exercise3 = FactoryGirl.create(:exercise, course: @course) @@ -40,7 +39,7 @@ end def do_get - get :show, organization_id: @organization.slug, course_id: @course.id, id: @user.id, format: :json, api_version: ApiVersion::API_VERSION + get :show, organization_id: @organization.slug, course_name: @course.name, id: @user.id, format: :json, api_version: ApiVersion::API_VERSION end it 'should show completition status for submitted exercises' do diff --git a/spec/controllers/exercises_controller_spec.rb b/spec/controllers/exercises_controller_spec.rb index ec89d4155..1ef034dca 100644 --- a/spec/controllers/exercises_controller_spec.rb +++ b/spec/controllers/exercises_controller_spec.rb @@ -4,13 +4,12 @@ describe 'GET show' do before :each do @organization = FactoryGirl.create(:accepted_organization) - @course = FactoryGirl.create(:course) - @course.organization = @organization + @course = FactoryGirl.create(:course, organization: @organization) end let!(:exercise) { FactoryGirl.create(:exercise, course: @course) } def get_show - get :show, organization_id: @organization.slug, id: exercise.id + get :show, organization_id: @organization.slug, course_name: @course.name, name: exercise.name end describe 'for guests' do @@ -69,7 +68,7 @@ def get_show end def post_set_disabled_statuses(options = {}) - post :set_disabled_statuses, options.merge(organization_id: @organization.slug, course_id: @course.id) + post :set_disabled_statuses, options.merge(organization_id: @organization.slug, course_name: @course.name) end describe 'as a teacher' do diff --git a/spec/controllers/points_controller_spec.rb b/spec/controllers/points_controller_spec.rb index 112e34dc3..6450132ae 100644 --- a/spec/controllers/points_controller_spec.rb +++ b/spec/controllers/points_controller_spec.rb @@ -7,7 +7,7 @@ before :each do @user = FactoryGirl.create(:user) @organization = FactoryGirl.create(:accepted_organization) - @course = FactoryGirl.create :course, organization: @organization + @course = FactoryGirl.create(:course, organization: @organization) @sheetname = 'testsheet' @exercise = FactoryGirl.create(:exercise, course: @course, gdocs_sheet: @sheetname) @submission = FactoryGirl.create(:submission, @@ -26,14 +26,14 @@ describe 'GET index' do describe 'when user has participated in a course' do it 'should show a page' do - get :index, organization_id: @organization.slug, course_id: @course.id + get :index, organization_id: @organization.slug, course_name: @course.name expect(response).to be_success end it 'should not show a page when submission result are hidden' do @course.hide_submission_results = true @course.save! - get :index, organization_id: @organization.slug, course_id: @course.id + get :index, organization_id: @organization.slug, course_name: @course.name expect(response.code.to_i).to eq(401) end end @@ -43,29 +43,29 @@ describe 'when user has participated in a course' do it 'should show a page' do get :show, organization_id: @organization.slug, - course_id: @course.id, id: @sheetname + course_name: @course.name, id: @sheetname expect(response).to be_success end it 'should contain @user login' do - get :show, organization_id: @organization.slug, course_id: @course.id, id: @sheetname + get :show, organization_id: @organization.slug, course_name: @course.name, id: @sheetname expect(response.body).to have_content(@user.login) end it 'should contain available point name' do - get :show, organization_id: @organization.slug, course_id: @course.id, id: @sheetname + get :show, organization_id: @organization.slug, course_name: @course.name, id: @sheetname expect(response.body).to have_content(@available_point.name) end it 'should contain a success marker' do - get :show, organization_id: @organization.slug, course_id: @course.id, id: @sheetname + get :show, organization_id: @organization.slug, course_name: @course.name, id: @sheetname expect(response.body).to have_content('✔') end it 'should not show a page when submission result are hidden' do @course.hide_submission_results = true @course.save! - get :show, organization_id: @organization.slug, course_id: @course.id, id: @sheetname + get :show, organization_id: @organization.slug, course_name: @course.name, id: @sheetname expect(response.code.to_i).to eq(401) end end diff --git a/spec/features/teacher_adds_assistants_to_course_spec.rb b/spec/features/teacher_adds_assistants_to_course_spec.rb index eb4e0e5a5..c7fe43492 100644 --- a/spec/features/teacher_adds_assistants_to_course_spec.rb +++ b/spec/features/teacher_adds_assistants_to_course_spec.rb @@ -49,7 +49,7 @@ log_out log_in_as(@assistant.username, 'newfoobar') - visit "/org/slug/courses/#{@course.id}" + visit "/org/slug/courses/#{@course.name}" click_link 'Manage deadlines' fill_in 'empty_group_hard_static', with: '1.1.2000' click_button 'Save changes' @@ -57,7 +57,7 @@ expect(page).to have_content('Successfully saved deadlines.') expect(page).to have_field('empty_group_hard_static', with: '1.1.2000') - visit "/org/slug/courses/#{@course.id}" + visit "/org/slug/courses/#{@course.name}" click_link 'Manage unlock conditions' fill_in 'empty_group_0', with: '4.6.2015' @@ -74,7 +74,7 @@ log_out log_in_as(@assistant.username, 'newfoobar') - visit "/org/slug/courses/#{course2.id}" + visit "/org/slug/courses/#{course2.name}" expect(page).not_to have_content('Manage deadlines') expect(page).not_to have_content('Manage unlock conditions') end diff --git a/spec/features/teacher_disables_exercises_spec.rb b/spec/features/teacher_disables_exercises_spec.rb index 853008f1f..a30e51367 100644 --- a/spec/features/teacher_disables_exercises_spec.rb +++ b/spec/features/teacher_disables_exercises_spec.rb @@ -89,12 +89,12 @@ log_in_as(@user.login, @user.password) - visit "/exercises/#{@ex1.id}" + visit "/org/slug/courses/#{@course.name}/exercises/#{@ex1.name}" expect(page).to have_content('Access denied') end def visit_course(course) - visit "/org/slug/courses/#{course.id}" + visit "/org/slug/courses/#{course.name}" end end diff --git a/spec/features/teacher_edits_unlock_dates_spec.rb b/spec/features/teacher_edits_unlock_dates_spec.rb index ed4e23b94..71db7c3c9 100644 --- a/spec/features/teacher_edits_unlock_dates_spec.rb +++ b/spec/features/teacher_edits_unlock_dates_spec.rb @@ -24,7 +24,7 @@ end def visit_course - visit "/org/slug/courses/#{@course.id}" + visit "/org/slug/courses/#{@course.name}" end scenario 'Teacher sees default unlock dates' do diff --git a/spec/features/teacher_has_admin_abilities_to_own_course_spec.rb b/spec/features/teacher_has_admin_abilities_to_own_course_spec.rb index 08e984e59..d2be4bcae 100644 --- a/spec/features/teacher_has_admin_abilities_to_own_course_spec.rb +++ b/spec/features/teacher_has_admin_abilities_to_own_course_spec.rb @@ -28,8 +28,12 @@ log_in_as(@teacher.login, 'xooxer') end + def visit_course + visit "/org/slug/courses/#{@course.name}" + end + scenario 'Teacher can see model solution for exercise' do - visit '/exercises/1' + visit "/org/slug/courses/#{@course.name}/exercises/#{@exercise1.name}" expect(page).to have_content('View suggested solution') click_link 'View suggested solution' @@ -39,7 +43,7 @@ end scenario 'Teacher can see all submissions for his organizations courses' do - visit '/org/slug/courses/1' + visit_course expect(page).to have_content('Latest submissions') expect(page).not_to have_content('No data available in table') @@ -56,7 +60,7 @@ scenario 'Teacher can see users points from his own courses' do available_point = FactoryGirl.create :available_point, exercise: @exercise1 available_point.award_to(@student, @submission) - visit '/org/slug/courses/1' + visit_course click_link 'View points' expect(page).to have_content('1/6') @@ -64,7 +68,7 @@ end scenario 'Teacher can make code review' do - visit '/org/slug/courses/1' + visit_course expect(page).to have_content('1 code review requested') click_link '1 code review requested' @@ -77,7 +81,7 @@ end scenario 'Teacher can manage course feedback questions' do - visit '/org/slug/courses/1' + visit_course click_link 'Manage feedback questions' click_link 'Add question' @@ -104,7 +108,7 @@ question = FactoryGirl.create :feedback_question, course: @course, question: 'Meaning of life?' answer = FactoryGirl.create :feedback_answer, feedback_question: question, course: @course, exercise: @exercise1, submission: @submission, answer: 'no idea' - visit '/org/slug/courses/1' + visit_course click_link 'View feedback' expect(page).not_to have_content('access denied') diff --git a/spec/features/teacher_hides_submission_results_spec.rb b/spec/features/teacher_hides_submission_results_spec.rb index 9d1da3a1c..54fb75200 100644 --- a/spec/features/teacher_hides_submission_results_spec.rb +++ b/spec/features/teacher_hides_submission_results_spec.rb @@ -28,7 +28,7 @@ end def visit_course - visit "/org/#{@organization.slug}/courses/#{@course.id}" + visit "/org/#{@organization.slug}/courses/#{@course.name}" end scenario "Teacher can see button 'Unhide submisson results' when result are hidden" do diff --git a/spec/features/teacher_sets_deadlines_spec.rb b/spec/features/teacher_sets_deadlines_spec.rb index cc3e919de..f7cc97380 100644 --- a/spec/features/teacher_sets_deadlines_spec.rb +++ b/spec/features/teacher_sets_deadlines_spec.rb @@ -29,7 +29,7 @@ end def visit_course - visit "/org/slug/courses/#{@course.id}" + visit "/org/slug/courses/#{@course.name}" end scenario 'Teacher succeeds at setting deadlines' do diff --git a/spec/features/teacher_show_course_json_spec.rb b/spec/features/teacher_show_course_json_spec.rb index e3701f5a0..f967aca35 100644 --- a/spec/features/teacher_show_course_json_spec.rb +++ b/spec/features/teacher_show_course_json_spec.rb @@ -17,7 +17,7 @@ end scenario 'Page returns organizations courses as json' do - visit "/org/slug/courses/#{@course.id}/courses.json?api_version=7" + visit "/org/slug/courses/#{@course.name}/courses.json?api_version=7" expect(page).to have_content('course_1') expect(page).not_to have_content('course_2')