Skip to content

Commit

Permalink
Merge branch 'main' into feat/debug-with-papyros
Browse files Browse the repository at this point in the history
  • Loading branch information
jorg-vr committed Feb 13, 2024
2 parents ec03930 + 1ed2ac3 commit 00151bc
Show file tree
Hide file tree
Showing 19 changed files with 205 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ jobs:
runs-on: ubuntu-latest
steps:
# Drafts next release notes as Pull Requests are merged into "main"
- uses: toolmantim/release-drafter@v5.25.0
- uses: toolmantim/release-drafter@v6.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
sudo sysctl -p
bundle exec rails test
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: rails
Expand All @@ -72,7 +72,7 @@ jobs:
run: |
yarn test --ci --runInBand --coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: javascript
Expand Down Expand Up @@ -131,7 +131,7 @@ jobs:
run: |
yarn test:system:coverage:merge
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: system
10 changes: 5 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ruby '~> 3.1.2'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 7.1.3'
# Use mysql as the database for Active Record
gem 'mysql2', '~> 0.5.5'
gem 'mysql2', '~> 0.5.6'
# Use Puma as the app server
gem 'puma', '~> 6.4.2'

Expand Down Expand Up @@ -34,7 +34,7 @@ gem 'jbuilder', '~> 2.11.5'
gem 'image_processing', '~> 1.12.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '~> 1.17.1', require: false
gem 'bootsnap', '~> 1.18.3', require: false

# used to validate container responses
gem 'json_schemer', '~> 2.1.1'
Expand Down Expand Up @@ -111,7 +111,7 @@ gem 'httparty', '~> 0.21.0'
gem 'slack-notifier', '~> 2.4.0'

# css styles for emails
gem 'nokogiri', '~> 1.16.0'
gem 'nokogiri', '~> 1.16.2'
gem 'premailer-rails', '~> 1.12.0'

# filtering
Expand All @@ -132,10 +132,10 @@ gem 'memory_profiler', '~> 1.0.1'
gem 'rack-mini-profiler', '~> 3.3.0'
gem 'stackprof', '~> 0.2.26'

gem 'ddtrace', '~> 1.19.0'
gem 'ddtrace', '~> 1.20.0'

# Make sure filesystem changes only happen at the end of a transaction
gem 'after_commit_everywhere', '~> 1.3.1'
gem 'after_commit_everywhere', '~> 1.4.0'

# More advanced counter_cache that allows conditions
gem 'counter_culture', '~> 3.5'
Expand Down
35 changes: 18 additions & 17 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ GEM
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
aes_key_wrap (1.1.0)
after_commit_everywhere (1.3.1)
after_commit_everywhere (1.4.0)
activerecord (>= 4.2)
activesupport
airbrussh (1.4.1)
Expand All @@ -96,7 +96,7 @@ GEM
bigdecimal (3.1.6)
bindata (2.4.15)
bindex (0.8.1)
bootsnap (1.17.1)
bootsnap (1.18.3)
msgpack (~> 1.2)
builder (3.2.4)
byebug (11.1.3)
Expand Down Expand Up @@ -134,7 +134,8 @@ GEM
counter_culture (3.5.2)
activerecord (>= 4.2)
activesupport (>= 4.2)
crack (0.4.5)
crack (1.0.0)
bigdecimal
rexml
crass (1.0.6)
css_parser (1.12.0)
Expand All @@ -144,11 +145,11 @@ GEM
daemons (1.4.1)
dalli (3.2.7)
base64
datadog-ci (0.6.0)
datadog-ci (0.7.0)
msgpack
date (3.3.4)
ddtrace (1.19.0)
datadog-ci (~> 0.6.0)
ddtrace (1.20.0)
datadog-ci (~> 0.7.0)
debase-ruby_core_source (= 3.3.1)
libdatadog (~> 5.0.0.1.0)
libddwaf (~> 1.14.0.0.0)
Expand All @@ -170,7 +171,7 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
diff-lcs (1.5.0)
diff-lcs (1.5.1)
docile (1.4.0)
docker-api (2.2.0)
excon (>= 0.47.0)
Expand Down Expand Up @@ -206,7 +207,7 @@ GEM
has_scope (0.8.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
hashdiff (1.0.1)
hashdiff (1.1.0)
hashie (5.0.0)
hcaptcha (7.1.0)
json
Expand Down Expand Up @@ -277,7 +278,7 @@ GEM
memory_profiler (1.0.1)
mini_magick (4.11.0)
mini_mime (1.1.5)
minitest (5.21.2)
minitest (5.22.2)
minitest-ci (3.4.0)
minitest (>= 5.0.6)
minitest-utils (0.4.8)
Expand All @@ -290,7 +291,7 @@ GEM
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
mutex_m (0.2.0)
mysql2 (0.5.5)
mysql2 (0.5.6)
net-imap (0.4.9.1)
date
net-protocol
Expand All @@ -304,7 +305,7 @@ GEM
net-protocol
net-ssh (7.1.0)
nio4r (2.7.0)
nokogiri (1.16.0-x86_64-linux)
nokogiri (1.16.2-x86_64-linux)
racc (~> 1.4)
oauth2 (2.0.8)
faraday (>= 0.17.3, < 3.0)
Expand Down Expand Up @@ -541,7 +542,7 @@ GEM
activesupport
faraday (~> 2.0)
faraday-follow_redirects
webmock (3.19.1)
webmock (3.20.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
Expand All @@ -559,11 +560,11 @@ PLATFORMS
x86_64-linux

DEPENDENCIES
after_commit_everywhere (~> 1.3.1)
after_commit_everywhere (~> 1.4.0)
annotate (~> 3.2.0)
autoprefixer-rails (~> 10.4.16)
bcrypt_pbkdf
bootsnap (~> 1.17.1)
bootsnap (~> 1.18.3)
builder (~> 3.2.4)
byebug (~> 11.1.3)
capistrano-passenger (~> 0.2.1)
Expand All @@ -575,7 +576,7 @@ DEPENDENCIES
counter_culture (~> 3.5)
cssbundling-rails (~> 1.4.0)
dalli (~> 3.2.7)
ddtrace (~> 1.19.0)
ddtrace (~> 1.20.0)
delayed_job_active_record (~> 4.1.8)
delayed_job_web (~> 1.4.4)
devise (~> 4.9.3)
Expand Down Expand Up @@ -606,8 +607,8 @@ DEPENDENCIES
minitest-ci (~> 3.4.0)
minitest-utils (~> 0.4.8)
mocha (~> 2.1.0)
mysql2 (~> 0.5.5)
nokogiri (~> 1.16.0)
mysql2 (~> 0.5.6)
nokogiri (~> 1.16.2)
omniauth-google-oauth2 (~> 1.1.1)
omniauth-oauth2 (~> 1.8.0)
omniauth-rails_csrf_protection (~> 1.0.1)
Expand Down
6 changes: 6 additions & 0 deletions app/assets/javascripts/favorite_course_buttons.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Toast } from "./toast";
import { fetch, getParentByClassName } from "utilities";
import { i18n } from "i18n/i18n";
import { SeriesIcon } from "components/series_icon";

function initFavoriteButtons(doc: Document | HTMLElement = document): void {
function init(): void {
Expand Down Expand Up @@ -44,6 +45,11 @@ function initFavoriteButtons(doc: Document | HTMLElement = document): void {
cloneFavButton.setAttribute("title", i18n.t("js.unfavorite-course-do"));
new bootstrap.Tooltip(cloneFavButton); // is enabled by default
cloneFavButton.addEventListener("click", toggleFavorite);
// hack to fix double rendering of content of lit element 'd-series-icon'
clone.querySelectorAll("d-series-icon").forEach((el: SeriesIcon) => {
el.replaceChildren();
el.requestUpdate();
});
} else {
new Toast(i18n.t("js.favorite-course-failed"));
}
Expand Down
5 changes: 3 additions & 2 deletions app/helpers/courses_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def registration_action_for(**args)

secret = args[:secret]
membership = args[:membership]
css_class = args[:class] || 'btn btn-filled'

if membership.nil? || membership.unsubscribed?
if course.open_for_user?(current_user) || current_user.nil?
Expand All @@ -13,13 +14,13 @@ def registration_action_for(**args)
subscribe_course_path(@course, secret: secret),
title: t('courses.registration.registration-tooltip'),
method: :post,
class: 'btn btn-filled'
class: css_class
else
link_to t('courses.show.subscribe'),
subscribe_course_path(@course, secret: secret),
title: t('courses.registration.registration-tooltip'),
method: :post,
class: 'btn btn-filled'
class: css_class
end
else
tag.p t("courses.show.registration-#{@course.registration}-info", institution: @course.institution&.name)
Expand Down
24 changes: 24 additions & 0 deletions app/models/activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Activity < ApplicationRecord
has_many :labels, through: :activity_labels

validates :path, uniqueness: { scope: :repository_id, case_sensitive: false }, allow_nil: true
validate :require_correct_submission_before_publish, on: :update

token_generator :repository_token, length: 64
token_generator :access_token
Expand Down Expand Up @@ -442,6 +443,19 @@ def types
end
end

def correct_submission?
return true if content_page?

submissions.any?(&:accepted?)
end

def valid_config?
config
true
rescue ConfigParseError
false
end

private

def activity_status_for(user, series = nil)
Expand Down Expand Up @@ -510,4 +524,14 @@ def unique_labels(hash)
hash['labels'] = hash['labels'].uniq if hash.key? 'labels'
hash
end

def require_correct_submission_before_publish
return if draft?
return unless draft_was

errors.add(:base, I18n.t('activerecord.errors.models.activity.no_correct_submission')) unless correct_submission?
errors.add(:base, I18n.t('activerecord.errors.models.activity.not_valid')) if not_valid?
errors.add(:base, I18n.t('activerecord.errors.models.activity.invalid_config')) unless valid_config?
self.draft = true if errors.any?
end
end
29 changes: 26 additions & 3 deletions app/views/activities/_draft_notice.html.erb
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
<% if @activity.draft? %>
<div class="alert alert-warning">
<div class="alert alert-warning draft-notice">
<i class="mdi mdi-file-document-edit-outline"></i>
<%= t "activities.show.alert_draft_html" %>
<%= t "activities.show.alert_draft.text_html" %>
<% if policy(@activity).edit? %>
<% edit_path = @series.present? ?
course_series_activity_path(@series&.course, @series, @activity, {activity: {draft: false}}) :
activity_path(@activity, {activity: {draft: false}})
%>
<%= link_to t("activities.show.alert_draft_edit"), edit_path, method: :put %>

<% if @activity.ok? && @activity.correct_submission? && @activity.valid_config? %>
<%= link_to t("activities.show.alert_draft.edit"), edit_path, method: :put %>
<% else %>
<div style="margin-left: 30px; margin-top: 8px;">
<%= t("activities.show.alert_draft.before_publish") %>
<div style="margin-left: 16px;">
<div>
<i class="mdi <%= @activity.valid_config? ? "mdi-check-circle-outline" : "mdi-alert-circle-outline" %>"></i>
<span><%= t('activities.show.alert_draft.valid_config') %></span>
</div>
<div>
<i class="mdi <%= @activity.ok? ? "mdi-check-circle-outline" : "mdi-alert-circle-outline" %>"></i>
<span><%= t('activities.show.alert_draft.is_valid') %></span>
</div>
<% if @activity.exercise? %>
<div>
<i class="mdi <%= @activity.correct_submission? ? "mdi-check-circle-outline" : "mdi-alert-circle-outline" %>"></i>
<span><%= t('activities.show.alert_draft.correct_submission') %></span>
</div>
<% end %>
</div>
</div>
<% end %>

<% end %>
</div>
Expand Down
15 changes: 13 additions & 2 deletions app/views/courses/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,21 @@

<% if @course.description.present? or current_user&.member_of?(@course).! %>
<div class="card-supporting-text card-border row course-description">
<div class="col-sm-<%= current_user&.member_of?(@course).! ? '6' : '12' %> col-12">
<div class="col-sm-<%= (@course.featured? && policy(@course).copy?) || current_user&.member_of?(@course).! ? '6' : '12' %> col-12">
<%= cache @course do %>
<%= markdown(@course.description) %>
<% end %>
</div>
<% if current_user&.member_of?(@course).! %>
<% if @course.featured? && policy(@course).copy? %>
<div class="col-sm-6 col-12">
<div class="callout callout-info">
<p><%= t(".copy_info_html") %></p>
<%= link_to new_course_url(copy_options: {base_id: @course.id}), class: "btn btn-filled with-icon" do %>
<i class="mdi mdi-content-copy mdi-18"></i> <%= t(".copy") %>
<% end %>
</div>
</div>
<% elsif current_user&.member_of?(@course).! %>
<%= render partial: 'not_a_member_card' %>
<% if @lti_launch %>
<%= render partial: 'not_a_member_dialog' %>
Expand All @@ -55,6 +64,8 @@
<div class="card-actions card-border">
<% if current_user&.member_of? @course %>
<%= button_to t('.unsubscribe'), unsubscribe_course_path(@course), class: 'btn btn-text', data: {confirm: t('general.are_you_sure')} %>
<% elsif @course.featured? and policy(@course).copy? %>
<%= registration_action_for course: @course, membership: @current_membership, secret: (@course.secret if @course.secret_required?(current_user)), class: 'btn btn-text' %>
<% end %>
<% if policy(@course).copy? or policy(@course).scoresheet? or policy(@course).download_submissions? %>
<a class="btn btn-icon dropdown-toggle hidden-print" data-bs-toggle="dropdown">
Expand Down
4 changes: 4 additions & 0 deletions config/locales/models/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ en:
activerecord:
errors:
models:
activity:
no_correct_submission: "At least one correct submission is required, before the exercise can be published."
not_valid: "The exercise must have a name and a description."
invalid_config: "The JSON configuration is invalid."
course_membership:
at_least_one_admin: The course should always have at least one course administrator.
api_token:
Expand Down
4 changes: 4 additions & 0 deletions config/locales/models/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ nl:
activerecord:
errors:
models:
activity:
no_correct_submission: "Er moet minstens één correcte oplossing zijn, vooraleer de oefening kan worden gepubliceerd."
not_valid: "De oefening moet een naam en een beschrijving hebben."
invalid_config: "De JSON-configuratie is ongeldig."
course_membership:
at_least_one_admin: Een cursus moet altijd minstens één cursusbeheerder hebben.
api_token:
Expand Down
Loading

0 comments on commit 00151bc

Please sign in to comment.