Introduce new enabled
option for CodeHarbor
* Fix tests to ensure they work independent of config option
This commit is contained in:
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
class CodeharborLinksController < ApplicationController
|
class CodeharborLinksController < ApplicationController
|
||||||
include CommonBehavior
|
include CommonBehavior
|
||||||
|
before_action :verify_codeharbor_activation
|
||||||
before_action :set_codeharbor_link, only: %i[show edit update destroy]
|
before_action :set_codeharbor_link, only: %i[show edit update destroy]
|
||||||
|
|
||||||
def new
|
def new
|
||||||
base_url = CodeOcean::Config.new(:code_ocean).read[:codeharbor][:url]
|
base_url = CodeOcean::Config.new(:code_ocean).read[:codeharbor][:url] || ''
|
||||||
@codeharbor_link = CodeharborLink.new(push_url: base_url + '/import_exercise', check_uuid_url: base_url + '/import_uuid_check')
|
@codeharbor_link = CodeharborLink.new(push_url: base_url + '/import_exercise', check_uuid_url: base_url + '/import_uuid_check')
|
||||||
authorize!
|
authorize!
|
||||||
end
|
end
|
||||||
@ -36,6 +37,10 @@ class CodeharborLinksController < ApplicationController
|
|||||||
authorize @codeharbor_link
|
authorize @codeharbor_link
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def verify_codeharbor_activation
|
||||||
|
raise Pundit::NotAuthorizedError unless policy(CodeharborLink).enabled?
|
||||||
|
end
|
||||||
|
|
||||||
def set_codeharbor_link
|
def set_codeharbor_link
|
||||||
@codeharbor_link = CodeharborLink.find(params[:id])
|
@codeharbor_link = CodeharborLink.find(params[:id])
|
||||||
@codeharbor_link.user = current_user
|
@codeharbor_link.user = current_user
|
||||||
|
@ -8,23 +8,27 @@ class CodeharborLinkPolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def new?
|
def new?
|
||||||
teacher? || admin?
|
enabled? && (teacher? || admin?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create?
|
def create?
|
||||||
teacher? || admin?
|
enabled? && (teacher? || admin?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit?
|
def edit?
|
||||||
owner?
|
enabled? && owner?
|
||||||
end
|
end
|
||||||
|
|
||||||
def update?
|
def update?
|
||||||
owner?
|
enabled? && owner?
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy?
|
def destroy?
|
||||||
owner?
|
enabled? && owner?
|
||||||
|
end
|
||||||
|
|
||||||
|
def enabled?
|
||||||
|
CodeOcean::Config.new(:code_ocean).read[:codeharbor][:enabled]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -4,6 +4,6 @@ test:
|
|||||||
code_pilot:
|
code_pilot:
|
||||||
enabled: false
|
enabled: false
|
||||||
codeharbor:
|
codeharbor:
|
||||||
url: http://test.url
|
enabled: true
|
||||||
codeocean_events:
|
codeocean_events:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
@ -4,6 +4,8 @@ default: &default
|
|||||||
answers_per_query: 3
|
answers_per_query: 3
|
||||||
code_pilot:
|
code_pilot:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
codeharbor:
|
||||||
|
enabled: false
|
||||||
codeocean_events:
|
codeocean_events:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ development:
|
|||||||
enabled: false
|
enabled: false
|
||||||
url: //localhost:3000
|
url: //localhost:3000
|
||||||
codeharbor:
|
codeharbor:
|
||||||
|
enabled: true
|
||||||
url: https://codeharbor.openhpi.de
|
url: https://codeharbor.openhpi.de
|
||||||
|
|
||||||
production:
|
production:
|
||||||
|
@ -161,7 +161,7 @@ de:
|
|||||||
exercise_collection_item:
|
exercise_collection_item:
|
||||||
exercise: "Aufgabe"
|
exercise: "Aufgabe"
|
||||||
models:
|
models:
|
||||||
code_harbor_link:
|
codeharbor_link:
|
||||||
one: CodeHarbor-Link
|
one: CodeHarbor-Link
|
||||||
other: CodeHarbor-Links
|
other: CodeHarbor-Links
|
||||||
consumer:
|
consumer:
|
||||||
@ -269,13 +269,13 @@ de:
|
|||||||
codeharbor_link:
|
codeharbor_link:
|
||||||
generate: Generieren
|
generate: Generieren
|
||||||
info:
|
info:
|
||||||
push_url: Die Url von Codeharbor zu der die Aufgabe exportiert werden soll. Bei Unklarheiten bitte an einen Admin wenden.
|
push_url: Die Url von CodeHarbor zu der die Aufgabe exportiert werden soll. Bei Unklarheiten bitte an einen Admin wenden.
|
||||||
check_uuid_url: Die Url von Codeharbor an der geprüft werden kann, ob die Aufgabe schon existiert. Bei Unklarheiten bitte an einen Admin wenden.
|
check_uuid_url: Die Url von CodeHarbor an der geprüft werden kann, ob die Aufgabe schon existiert. Bei Unklarheiten bitte an einen Admin wenden.
|
||||||
api_key: Wird zum Authentifizieren gegenüber Codeharbor genutzt. Auf Codeharbor muss der gleiche Key eingetragen sein.
|
api_key: Wird zum Authentifizieren gegenüber CodeHarbor genutzt. Auf CodeHarbor muss der gleiche Key eingetragen sein.
|
||||||
profile_label: Codeharbor Link
|
profile_label: CodeHarbor-Link
|
||||||
new: Neue Codeharbor Link anlegen
|
new: Neuen CodeHarbor-Link anlegen
|
||||||
edit: Codeharbor Link bearbeiten
|
edit: CodeHarbor-Link bearbeiten
|
||||||
delete: Codeharbor Link entfernen
|
delete: CodeHarbor-Link entfernen
|
||||||
execution_environments:
|
execution_environments:
|
||||||
form:
|
form:
|
||||||
hints:
|
hints:
|
||||||
@ -350,21 +350,21 @@ de:
|
|||||||
invalid: Fehlerhafte Aufgabe
|
invalid: Fehlerhafte Aufgabe
|
||||||
internal_error: Beim Import der Aufgabe ist ein interner Fehler aufgetreten.
|
internal_error: Beim Import der Aufgabe ist ein interner Fehler aufgetreten.
|
||||||
export_codeharbor:
|
export_codeharbor:
|
||||||
label: Zu Codeharbor exportieren
|
label: Zu CodeHarbor exportieren
|
||||||
dialogtitle: Zu Codeharbor exportieren
|
dialogtitle: Zu CodeHarbor exportieren
|
||||||
successfully_exported: 'Aufgabe wurde erfolgreich exportiert.<br>ID: %{id}<br>Title: %{title}'
|
successfully_exported: 'Aufgabe wurde erfolgreich exportiert.<br>ID: %{id}<br>Title: %{title}'
|
||||||
export_failed: 'Export ist fehlgeschlagen.<br>ID: %{id}<br>Title: %{title}<br><br>Error: %{error}'
|
export_failed: 'Export ist fehlgeschlagen.<br>ID: %{id}<br>Title: %{title}<br><br>Error: %{error}'
|
||||||
error: Es ist ein Fehler bei der Kommunikation mit Codeharbor aufgetreten.
|
error: Es ist ein Fehler bei der Kommunikation mit CodeHarbor aufgetreten.
|
||||||
checking_codeharbor: Es wird geprüft, ob auf Codeharbor eine korrespondierende Aufgabe gefunden werden kann.
|
checking_codeharbor: Es wird geprüft, ob auf CodeHarbor eine korrespondierende Aufgabe gefunden werden kann.
|
||||||
buttons:
|
buttons:
|
||||||
retry: Erneut probieren
|
retry: Erneut probieren
|
||||||
export: Export
|
export: Export
|
||||||
close: Schließen
|
close: Schließen
|
||||||
abort: Abbrechen
|
abort: Abbrechen
|
||||||
check:
|
check:
|
||||||
no_exercise: Auf Codeharbor wurde keine entsprechende Aufgabe gefunden. Mit dem Export der Aufgabe wird eine neue auf Codeharbor angelegt, die mit dieser verbunden ist. Anschließend können Veränderungen an der Aufgabe von beiden Systemen aus jeweils in das andere Übertragen werden.
|
no_exercise: Auf CodeHarbor wurde keine entsprechende Aufgabe gefunden. Mit dem Export der Aufgabe wird eine neue auf CodeHarbor angelegt, die mit dieser verbunden ist. Anschließend können Veränderungen an der Aufgabe von beiden Systemen aus jeweils in das andere Übertragen werden.
|
||||||
exercise_found: Auf Codeharbor wurde eine entsprechende Aufgabe gefunden. Mit dem Export der Aufgabe werden alle Veränderungen, die auf Codeocean vorgenommen wurden, exportiert und die Aufgabe auf Codeharbor überschrieben.
|
exercise_found: Auf CodeHarbor wurde eine entsprechende Aufgabe gefunden. Mit dem Export der Aufgabe werden alle Veränderungen, die auf Codeocean vorgenommen wurden, exportiert und die Aufgabe auf CodeHarbor überschrieben.
|
||||||
exercise_found_no_right: Auf Codeharbor wurde eine entsprechende Aufgabe gefunden, Sie haben aber keine Rechte sie zu bearbeiten. Bitte wenden Sie sich an einen Admin, wenn Sie denken, dass Sie die Rechte dazu besitzen sollten.
|
exercise_found_no_right: Auf CodeHarbor wurde eine entsprechende Aufgabe gefunden, Sie haben aber keine Rechte sie zu bearbeiten. Bitte wenden Sie sich an einen Admin, wenn Sie denken, dass Sie die Rechte dazu besitzen sollten.
|
||||||
file_form:
|
file_form:
|
||||||
hints:
|
hints:
|
||||||
feedback_message: Diese Nachricht wird als Hinweis zu fehlschlagenden Tests angezeigt.
|
feedback_message: Diese Nachricht wird als Hinweis zu fehlschlagenden Tests angezeigt.
|
||||||
|
@ -161,7 +161,7 @@ en:
|
|||||||
exercise_collection_item:
|
exercise_collection_item:
|
||||||
exercise: "Exercise"
|
exercise: "Exercise"
|
||||||
models:
|
models:
|
||||||
code_harbor_link:
|
codeharbor_link:
|
||||||
one: CodeHarbor Link
|
one: CodeHarbor Link
|
||||||
other: CodeHarbor Links
|
other: CodeHarbor Links
|
||||||
consumer:
|
consumer:
|
||||||
@ -269,13 +269,13 @@ en:
|
|||||||
codeharbor_link:
|
codeharbor_link:
|
||||||
generate: Generate
|
generate: Generate
|
||||||
info:
|
info:
|
||||||
push_url: The url from Codeharbor where your exercise can be exported to. If you don't know what to write here, ask an admin.
|
push_url: The url from CodeHarbor where your exercise can be exported to. If you don't know what to write here, ask an admin.
|
||||||
check_uuid_url: The url from Codeharbor where we can check if the exercise already exists. If you don't know what to write here, ask an admin.
|
check_uuid_url: The url from CodeHarbor where we can check if the exercise already exists. If you don't know what to write here, ask an admin.
|
||||||
api_key: Will be used to authenticate your export request. Has to be the same on both sides.
|
api_key: Will be used to authenticate your export request. Has to be the same on both sides.
|
||||||
profile_label: Codeharbor Link
|
profile_label: CodeHarbor Link
|
||||||
new: Create link to Codeharbor
|
new: Create link to CodeHarbor
|
||||||
edit: Edit existing link
|
edit: Edit existing CodeHarbor link
|
||||||
delete: Remove Codeharbor link
|
delete: Remove CodeHarbor link
|
||||||
execution_environments:
|
execution_environments:
|
||||||
form:
|
form:
|
||||||
hints:
|
hints:
|
||||||
@ -350,21 +350,21 @@ en:
|
|||||||
invalid: Invalid exercise
|
invalid: Invalid exercise
|
||||||
internal_error: An internal error occurred on CodeOcean while importing the exercise.
|
internal_error: An internal error occurred on CodeOcean while importing the exercise.
|
||||||
export_codeharbor:
|
export_codeharbor:
|
||||||
label: Export to Codeharbor
|
label: Export to CodeHarbor
|
||||||
dialogtitle: Export to Codeharbor
|
dialogtitle: Export to CodeHarbor
|
||||||
successfully_exported: 'Exercise has been successfully exported.<br>ID: %{id}<br>Title: %{title}'
|
successfully_exported: 'Exercise has been successfully exported.<br>ID: %{id}<br>Title: %{title}'
|
||||||
export_failed: 'Export has failed.<br>ID: %{id}<br>Title: %{title}<br><br>Error: %{error}'
|
export_failed: 'Export has failed.<br>ID: %{id}<br>Title: %{title}<br><br>Error: %{error}'
|
||||||
error: 'An error occurred while contacting Codeharbor'
|
error: 'An error occurred while contacting CodeHarbor'
|
||||||
checking_codeharbor: Checking if the exercise exists on Codeharbor.
|
checking_codeharbor: Checking if the exercise exists on CodeHarbor.
|
||||||
buttons:
|
buttons:
|
||||||
retry: Retry
|
retry: Retry
|
||||||
export: Export
|
export: Export
|
||||||
close: Close
|
close: Close
|
||||||
abort: Abort
|
abort: Abort
|
||||||
check:
|
check:
|
||||||
no_exercise: No corresponding exercise found on Codeharbor. Pushing this exercise will create a new exercise on Codeharbor, which will be linked to this one on Codeocean. Any changes to either one can be pushed to the respective other platform.
|
no_exercise: No corresponding exercise found on CodeHarbor. Pushing this exercise will create a new exercise on CodeHarbor, which will be linked to this one on Codeocean. Any changes to either one can be pushed to the respective other platform.
|
||||||
exercise_found: 'A corresponding exercise has been found on Codeharbor. You can export the exercise to transfer all changes made on Codeocean to Codeharbor. Careful: This will overwrite all potential changes made on Codeharbor.'
|
exercise_found: 'A corresponding exercise has been found on CodeHarbor. You can export the exercise to transfer all changes made on Codeocean to CodeHarbor. Careful: This will overwrite all potential changes made on CodeHarbor.'
|
||||||
exercise_found_no_right: A corresponding exercise has been found on Codeharbor, but you don't have the rights to edit it. Please contact an Admin if you think you should be able to edit the exercise on Codeharbor.
|
exercise_found_no_right: A corresponding exercise has been found on CodeHarbor, but you don't have the rights to edit it. Please contact an Admin if you think you should be able to edit the exercise on CodeHarbor.
|
||||||
file_form:
|
file_form:
|
||||||
hints:
|
hints:
|
||||||
feedback_message: This message is used as a hint for failing tests.
|
feedback_message: This message is used as a hint for failing tests.
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe CodeharborLinksController do
|
describe CodeharborLinksController do
|
||||||
let(:user) { FactoryBot.create(:teacher) }
|
let(:user) { FactoryBot.create(:teacher) }
|
||||||
before(:each) { allow(controller).to receive(:current_user).and_return(user) }
|
|
||||||
|
|
||||||
describe 'GET #new' do
|
let(:codeocean_config) { instance_double(CodeOcean::Config) }
|
||||||
before { get :new }
|
let(:codeharbor_config) { {codeharbor: {enabled: true, url: 'http://test.url'}} }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(CodeOcean::Config).to receive(:new).with(:code_ocean).and_return(codeocean_config)
|
||||||
|
allow(codeocean_config).to receive(:read).and_return(codeharbor_config)
|
||||||
|
allow(controller).to receive(:current_user).and_return(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'GET #new' do
|
||||||
|
before do
|
||||||
|
get :new
|
||||||
|
end
|
||||||
|
|
||||||
expect_status(200)
|
expect_status(200)
|
||||||
end
|
end
|
||||||
@ -13,7 +25,7 @@ describe CodeharborLinksController do
|
|||||||
describe 'GET #edit' do
|
describe 'GET #edit' do
|
||||||
let(:codeharbor_link) { FactoryBot.create(:codeharbor_link, user: user) }
|
let(:codeharbor_link) { FactoryBot.create(:codeharbor_link, user: user) }
|
||||||
|
|
||||||
before { get :edit, params: { id: codeharbor_link.id } }
|
before { get :edit, params: {id: codeharbor_link.id} }
|
||||||
|
|
||||||
expect_status(200)
|
expect_status(200)
|
||||||
end
|
end
|
||||||
@ -52,9 +64,11 @@ describe CodeharborLinksController do
|
|||||||
it 'updates push_url' do
|
it 'updates push_url' do
|
||||||
expect { put_request }.to change { codeharbor_link.reload.push_url }.to('http://foo.bar/push')
|
expect { put_request }.to change { codeharbor_link.reload.push_url }.to('http://foo.bar/push')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates check_uuid_url' do
|
it 'updates check_uuid_url' do
|
||||||
expect { put_request }.to change { codeharbor_link.reload.check_uuid_url }.to('http://foo.bar/check')
|
expect { put_request }.to change { codeharbor_link.reload.check_uuid_url }.to('http://foo.bar/check')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates api_key' do
|
it 'updates api_key' do
|
||||||
expect { put_request }.to change { codeharbor_link.reload.api_key }.to('api_key')
|
expect { put_request }.to change { codeharbor_link.reload.api_key }.to('api_key')
|
||||||
end
|
end
|
||||||
@ -67,7 +81,7 @@ describe CodeharborLinksController do
|
|||||||
let(:params) { {push_url: '', check_uuid_url: '', api_key: ''} }
|
let(:params) { {push_url: '', check_uuid_url: '', api_key: ''} }
|
||||||
|
|
||||||
it 'does not change codeharbor_link' do
|
it 'does not change codeharbor_link' do
|
||||||
expect { put_request }.not_to change { codeharbor_link.reload.attributes }
|
expect { put_request }.not_to(change { codeharbor_link.reload.attributes })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to user show' do
|
it 'redirects to user show' do
|
||||||
@ -90,4 +104,3 @@ describe CodeharborLinksController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe CodeharborLinkPolicy do
|
describe CodeharborLinkPolicy do
|
||||||
@ -5,37 +7,73 @@ describe CodeharborLinkPolicy do
|
|||||||
|
|
||||||
let(:codeharbor_link) { FactoryBot.create(:codeharbor_link) }
|
let(:codeharbor_link) { FactoryBot.create(:codeharbor_link) }
|
||||||
|
|
||||||
%i[index? show?].each do |action|
|
context 'when CodeHarbor link is enabled' do
|
||||||
permissions(action) do
|
let(:codeocean_config) { instance_double(CodeOcean::Config) }
|
||||||
it 'does not grant access any user' do
|
let(:codeharbor_config) { {codeharbor: {enabled: true}} }
|
||||||
%i[external_user teacher admin].each do |factory_name|
|
|
||||||
expect(policy).not_to permit(FactoryBot.create(factory_name), codeharbor_link)
|
before do
|
||||||
|
allow(CodeOcean::Config).to receive(:new).with(:code_ocean).and_return(codeocean_config)
|
||||||
|
allow(codeocean_config).to receive(:read).and_return(codeharbor_config)
|
||||||
|
end
|
||||||
|
|
||||||
|
%i[index? show?].each do |action|
|
||||||
|
permissions(action) do
|
||||||
|
it 'does not grant access any user' do
|
||||||
|
%i[external_user teacher admin].each do |factory_name|
|
||||||
|
expect(policy).not_to permit(FactoryBot.create(factory_name), codeharbor_link)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
%i[new? create?].each do |action|
|
%i[new? create?].each do |action|
|
||||||
permissions(action) do
|
permissions(action) do
|
||||||
it 'grants access to teachers' do
|
it 'grants access to teachers' do
|
||||||
%i[teacher admin].each do |factory_name|
|
%i[teacher admin].each do |factory_name|
|
||||||
|
expect(policy).to permit(FactoryBot.create(factory_name), codeharbor_link)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not grant access to all other users' do
|
||||||
|
expect(policy).not_to permit(FactoryBot.create(:external_user), codeharbor_link)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%i[destroy? edit? update?].each do |action|
|
||||||
|
permissions(action) do
|
||||||
|
it 'grants access to the owner of the link' do
|
||||||
|
expect(policy).to permit(codeharbor_link.user, codeharbor_link)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not grant access to arbitrary users' do
|
||||||
|
%i[external_user admin teacher].each do |factory_name|
|
||||||
|
expect(policy).not_to permit(FactoryBot.create(factory_name), codeharbor_link)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions(:enabled?) do
|
||||||
|
it 'reflects the config option' do
|
||||||
|
%i[external_user admin teacher].each do |factory_name|
|
||||||
expect(policy).to permit(FactoryBot.create(factory_name), codeharbor_link)
|
expect(policy).to permit(FactoryBot.create(factory_name), codeharbor_link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not grant access to all other users' do
|
|
||||||
expect(policy).not_to permit(FactoryBot.create(:external_user), codeharbor_link)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%i[destroy? edit? update?].each do |action|
|
context 'when CodeHabor link is disabled' do
|
||||||
permissions(action) do
|
let(:codeocean_config) { instance_double(CodeOcean::Config) }
|
||||||
it 'grants access to the owner of the link' do
|
let(:codeharbor_config) { {codeharbor: {enabled: false}} }
|
||||||
expect(policy).to permit(codeharbor_link.user, codeharbor_link)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not grant access to arbitrary users' do
|
before do
|
||||||
|
allow(CodeOcean::Config).to receive(:new).with(:code_ocean).and_return(codeocean_config)
|
||||||
|
allow(codeocean_config).to receive(:read).and_return(codeharbor_config)
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions(:enabled?) do
|
||||||
|
it 'reflects the config option' do
|
||||||
%i[external_user admin teacher].each do |factory_name|
|
%i[external_user admin teacher].each do |factory_name|
|
||||||
expect(policy).not_to permit(FactoryBot.create(factory_name), codeharbor_link)
|
expect(policy).not_to permit(FactoryBot.create(factory_name), codeharbor_link)
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user