Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions app/controllers/admin/answers_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
class Admin::AnswersController < Admin::BaseController

before_action :find_answer, only: %i[ edit show update destroy ]
before_action :find_question, only: %i[ new create ]

Expand All @@ -16,15 +15,15 @@ def create
@answer = @question.answers.new(answer_params)

if @answer.save
redirect_to admin_answer_path(@answer), notice: 'Answer was successfully created.'
redirect_to admin_answer_path(@answer), notice: "Answer was successfully created."
else
render :new
end
end

def update
if @answer.update(answer_params)
redirect_to admin_answer_path(@answer), notice: 'Answer was successfully update.'
redirect_to admin_answer_path(@answer), notice: "Answer was successfully update."
else
render :edit
end
Expand All @@ -36,7 +35,7 @@ def destroy
end


private
private

def find_answer
@answer = Answer.find(params[:id])
Expand Down
3 changes: 1 addition & 2 deletions app/controllers/admin/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
class Admin::BaseController < ApplicationController

layout 'admin'
layout "admin"

before_action :authenticate_user!
before_action :admin_required!
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/tests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def set_tests
end

def test_params
params.require(:test).permit(:title, :level, :category_id, :author_id)
params.require(:test).permit(:title, :level, :category_id, :author_id, :timer)
end

def find_test
Expand Down
3 changes: 1 addition & 2 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
class ApplicationController < ActionController::Base

protect_from_forgery with: :exception

before_action :configure_permitted_parameters, if: :devise_controller?
before_action :set_locale

def default_url_options
{ lang: ((I18n.locale == I18n.default_locale) ? nil : I18n.locale) }
{ lang: ((I18n.locale == I18n.default_locale) ? nil : I18n.locale) }
end


Expand Down
7 changes: 3 additions & 4 deletions app/controllers/gists_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class GistsController < ApplicationController

before_action :authenticate_user!

def create
test_passage = TestPassage.find(params[:test_passage_id])

Expand All @@ -10,7 +9,7 @@ def create
flash_answer = if result.success?
{ notice: "#{t('.success')} | #{link_in_gist(result.html_url)}" }
else
{ alert: t('.failure')}
{ alert: t(".failure") }
end

redirect_to test_passage, flash_answer
Expand All @@ -20,6 +19,6 @@ def create
private

def link_in_gist(gist_url)
view_context.link_to( t('helpers.link.go_gist'), gist_url, class: "link-dark link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover", target: '_blank')
view_context.link_to(t("helpers.link.go_gist"), gist_url, class: "link-dark link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover", target: "_blank")
end
end
3 changes: 1 addition & 2 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class SessionsController < Devise::SessionsController

def create
super
flash[:notice] = t('sessions_controller.welcome', name: resource.first_name || resource.email )
flash[:notice] = t("sessions_controller.welcome", name: resource.first_name || resource.email)
end
end
35 changes: 22 additions & 13 deletions app/controllers/test_passages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
class TestPassagesController < ApplicationController
before_action :authenticate_user!
before_action :set_test_passage, only: %i[ show result update ]
before_action :set_test_passage, only: %i[show result update]

def show; end

def result; end

def update
if @test_passage.question_any?(params)
@test_passage = TestPassage.find(params[:id])

if @test_passage.time_over?
flash[:alert] = t("test_passages.times_up")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

внутри if код разделяют отступами

if @test_passage.time_over?
  flash[:alert] = t("test_passages.times_up")
elsif
  @test_pass...
end

redirect_to result_test_passage_path(@test_passage)
elsif @test_passage.question_any?(params)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

если нет вопросов, значит тест завершился. А для этого есть уже подходящий метод #completed? который просто должен отвечать завершился ли тест. И не важно закончились вопросы и время. А сейчас получается что логику завершения теста не много размазали по коду

@test_passage.accept!(params[:answer_ids])

completed_test
Expand All @@ -16,6 +22,7 @@ def update
end
end


private

def set_test_passage
Expand All @@ -24,20 +31,22 @@ def set_test_passage

def completed_test
if @test_passage.completed?

TestMailer.completed_test(@test_passage).deliver_later

if @test_passage.test_successful?
new_badges = BadgeAwardService.new(@test_passage).call

if new_badges.any?
flash[:notice] = t("test_passages.badge", name_badge: new_badges.map(&:title).join(", "))
end
end

send_completion_notifications
award_badges
redirect_to result_test_passage_path(@test_passage)
else
redirect_to test_passage_path(@test_passage)
end
end

def send_completion_notifications
TestMailer.completed_test(@test_passage).deliver_later
end

def award_badges
new_badges = BadgeAwardService.new(@test_passage).call
return unless new_badges.any?

flash[:notice] = t("test_passages.badge", name_badge: new_badges.map(&:title).join(", "))
end
end
7 changes: 3 additions & 4 deletions app/controllers/tests_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
class TestsController < ApplicationController

def index
@tests = Test.all
end

def start
authenticate_user!
def start
authenticate_user!

current_user.tests.push(find_test)
redirect_to current_user.test_passage(find_test)
end
Expand Down
7 changes: 3 additions & 4 deletions app/helpers/answers_helper.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module AnswersHelper

def answer_header(answer)
if answer.new_record?
t('answers_helper.create_new_answer')
t("answers_helper.create_new_answer")
else
t('answers_helper.edit_answer', body: answer.body )
end
t("answers_helper.edit_answer", body: answer.body)
end
end
end
9 changes: 4 additions & 5 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module ApplicationHelper

def current_year
Time.current.year
end
Expand All @@ -11,10 +10,10 @@ def github_url(author, repo)
def flash_message
safe_join(flash.map do |flash_type, message|
alert_class = case flash_type.to_sym
when :notice, :success then 'alert-success'
when :alert, :error then 'alert-danger'
when :warning then 'alert-warning'
else 'alert-info'
when :notice, :success then "alert-success"
when :alert, :error then "alert-danger"
when :warning then "alert-warning"
else "alert-info"
end

content_tag :div, sanitize(message), class: "alert #{alert_class} my-4"
Expand Down
7 changes: 3 additions & 4 deletions app/helpers/questions_helper.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module QuestionsHelper

def question_header(question)
if question.new_record?
t('question_helper.create_new_question', question_title: question.test.title )
t("question_helper.create_new_question", question_title: question.test.title)
else
t('question_helper.edit_question', question_title: question.test.title )
end
t("question_helper.edit_question", question_title: question.test.title)
end
end
end
9 changes: 4 additions & 5 deletions app/helpers/test_passages_helper.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
module TestPassagesHelper

def success_rate_message(test_passage)
if test_passage.test_successful?
content_tag(:h3, I18n.t('test_passages_helper.success_rate_message.success_test'), class: 'text-start md-4') +
I18n.t('test_passages_helper.success_rate_message.rate') + content_tag(:span, "#{test_passage.result_test}%", style: "color: green;")
content_tag(:h3, I18n.t("test_passages_helper.success_rate_message.success_test"), class: "text-start md-4") +
I18n.t("test_passages_helper.success_rate_message.rate") + content_tag(:span, "#{test_passage.result_test}%", style: "color: green;")
else
content_tag(:h3, I18n.t('test_passages_helper.success_rate_message.failed_test'), class: 'text-start') +
I18n.t('test_passages_helper.success_rate_message.rate') + content_tag(:span, "#{test_passage.result_test}%", style: "color: red;")
content_tag(:h3, I18n.t("test_passages_helper.success_rate_message.failed_test"), class: "text-start") +
I18n.t("test_passages_helper.success_rate_message.rate") + content_tag(:span, "#{test_passage.result_test}%", style: "color: red;")
end
end
end
7 changes: 3 additions & 4 deletions app/helpers/tests_helper.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module TestsHelper

def test_header(test)
if test.new_record?
t('tests_helper.create_new_test')
t("tests_helper.create_new_test")
else
t('tests_helper.edit_test', test_title: test.title)
end
t("tests_helper.edit_test", test_title: test.title)
end
end
end
1 change: 1 addition & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ import "utilities/sorting"
import "utilities/check_password"
import "utilities/form_inline"
import "utilities/progress_bar"
import "utilities/timer"
31 changes: 31 additions & 0 deletions app/javascript/utilities/timer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
document.addEventListener("turbo:load", function() {
const timerElement = document.getElementById("timer");
if (!timerElement) return;

const form = document.getElementById("test-passage-form");
const initialMinutes = parseInt(timerElement.dataset.minutes) || 0;
const initialSeconds = parseInt(timerElement.dataset.seconds) || 0;
let totalSeconds = initialMinutes * 60 + initialSeconds;

function updateTimer() {
if (totalSeconds <= 0) {
clearInterval(timerInterval);
timerElement.textContent = "0:00";

if (form) form.submit();

return;
}

totalSeconds--;
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
}

const timerInterval = setInterval(updateTimer, 1000);

document.addEventListener("turbo:before-visit", () => {
clearInterval(timerInterval);
});
});
3 changes: 1 addition & 2 deletions app/mailers/test_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
class TestMailer < ApplicationMailer

def completed_test(test_passage)
@user = test_passage.user
@test = test_passage.test

mail to: @user.email
end
end
2 changes: 0 additions & 2 deletions app/models/admin.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
class Admin < User

validates :first_name, presence: true
validates :last_name, presence: true

end
1 change: 0 additions & 1 deletion app/models/answer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
class Answer < ApplicationRecord

belongs_to :question

validates :body, presence: true
Expand Down
6 changes: 2 additions & 4 deletions app/models/category.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
class Category < ApplicationRecord

has_many :tests

validates :title, presence: true

default_scope { order(title: :asc) }

end
2 changes: 0 additions & 2 deletions app/models/gist.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
class Gist < ApplicationRecord

belongs_to :question
belongs_to :user

end
2 changes: 2 additions & 0 deletions app/models/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class Test < ApplicationRecord

validates :level, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
validates :title, presence: true, uniqueness: { scope: :level }
validates :timer, numericality: { only_integer: true, greater_than_or_equal_to: 0 }


scope :easy_level, -> { where(level: 0..1) }
scope :average_level, -> { where(level: 2..4) }
Expand Down
38 changes: 38 additions & 0 deletions app/models/test_passage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,49 @@

before_validation :set_current_question


Check failure on line 10 in app/models/test_passage.rb

View workflow job for this annotation

GitHub Actions / lint

Layout/TrailingWhitespace: Trailing whitespace detected.
def timer_enabled?
test.timer != 0
end

def time_over?
return false unless timer_enabled? && !completed?
return false unless test_completion_time

Time.current >= test_completion_time
end

def test_completion_time
return unless test.timer.present?
created_at + (test.timer * 60)
end

def remaining_time
return unless timer_enabled?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут тоже хочеться рубокоп запустить

[ test_completion_time - Time.current, 0 ].max.round
end

def remaining_minutes
return unless remaining_time
(remaining_time / 60).floor
end

def remaining_seconds
return unless remaining_time
remaining_time % 60
end

def passed?
completed? && test_successful?
end

def accept!(answer_ids)
if time_over?
self.current_question = nil
save!
return
end

if correct_answer?(answer_ids)
self.correct_question += 1
end
Expand Down
Loading
Loading