From 4d1e2c5164739992f651277dc02f82cb589743ec Mon Sep 17 00:00:00 2001 From: Malaber Date: Mon, 10 Mar 2025 12:37:19 +0100 Subject: [PATCH] Add option to also pass seconds to timer_end --- app/controllers/tournaments_controller.rb | 38 +++++++--- .../tournaments_controller_spec.rb | 69 +++++++++++++------ 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/app/controllers/tournaments_controller.rb b/app/controllers/tournaments_controller.rb index 88c4de8..6cab8e9 100644 --- a/app/controllers/tournaments_controller.rb +++ b/app/controllers/tournaments_controller.rb @@ -181,16 +181,32 @@ end def validate_set_timer_end_params timer_end = params[:timer_end] - return render json: { error: 'Timer end is required' }, status: :unprocessable_entity unless timer_end.present? + timer_end_seconds = params[:timer_end_seconds] - begin - parsed_time = Time.zone.parse(timer_end) - if parsed_time.nil? - render json: { error: 'Invalid datetime format' }, status: :unprocessable_entity - elsif !parsed_time.future? - render json: { error: 'Timer end must be in the future' }, status: :unprocessable_entity - end - rescue ArgumentError - render json: { error: 'Invalid datetime format' }, status: :unprocessable_entity + # throw error if both timer_end and timer_end_seconds are present + if timer_end.present? && timer_end_seconds.present? + return render json: { error: 'Only one of timer_end or timer_end_seconds is allowed' }, status: :unprocessable_entity end -end \ No newline at end of file + + if timer_end_seconds.present? + begin + parsed_time = Time.zone.now + timer_end_seconds.to_i + params[:timer_end] = parsed_time + rescue ArgumentError + return render json: { error: 'Invalid seconds format' }, status: :unprocessable_entity + end + elsif timer_end.present? + begin + parsed_time = Time.zone.parse(timer_end) + if parsed_time.nil? + return render json: { error: 'Invalid datetime format' }, status: :unprocessable_entity + elsif !parsed_time.future? + return render json: { error: 'Timer end must be in the future' }, status: :unprocessable_entity + end + rescue ArgumentError + return render json: { error: 'Invalid datetime format' }, status: :unprocessable_entity + end + else + return render json: { error: 'Timer end is required' }, status: :unprocessable_entity + end +end diff --git a/spec/controllers/tournaments_controller_spec.rb b/spec/controllers/tournaments_controller_spec.rb index 9cd8bc5..5941ecd 100644 --- a/spec/controllers/tournaments_controller_spec.rb +++ b/spec/controllers/tournaments_controller_spec.rb @@ -483,37 +483,66 @@ RSpec.describe TournamentsController, type: :controller do apply_authentication_headers_for @tournament.owner @request.env['HTTP_ACCEPT'] = 'application/json' end + context 'timer_end' do + context 'when timer_end is missing' do + it 'returns unprocessable entity' do + patch :set_timer_end, params: { id: @tournament.id } + expect(response).to have_http_status(:unprocessable_entity) + expect(JSON.parse(response.body)).to include('error' => 'Timer end is required') + end + end - context 'when timer_end is missing' do - it 'returns unprocessable entity' do - patch :set_timer_end, params: { id: @tournament.id } - expect(response).to have_http_status(:unprocessable_entity) - expect(JSON.parse(response.body)).to include('error' => 'Timer end is required') + context 'when timer_end is invalid datetime' do + it 'returns unprocessable entity' do + patch :set_timer_end, params: { id: @tournament.id, timer_end: 'invalid' } + expect(response).to have_http_status(:unprocessable_entity) + expect(JSON.parse(response.body)).to include('error' => 'Invalid datetime format') + end + end + + context 'when timer_end is in the past' do + it 'returns unprocessable entity' do + patch :set_timer_end, params: { id: @tournament.id, timer_end: 1.day.ago } + expect(response).to have_http_status(:unprocessable_entity) + expect(JSON.parse(response.body)).to include('error' => 'Timer end must be in the future') + end + end + + context 'when timer_end is valid' do + it 'updates the timer_end' do + valid_timer_end = 1.day.from_now.change(usec: 0) + patch :set_timer_end, params: { id: @tournament.id, timer_end: valid_timer_end } + expect(response).to have_http_status(:ok) + expect(@tournament.reload.timer_end).to eq(valid_timer_end) + end end end - - context 'when timer_end is invalid datetime' do - it 'returns unprocessable entity' do - patch :set_timer_end, params: { id: @tournament.id, timer_end: 'invalid' } + context 'when timer_end_seconds is provided' do + it 'returns unprocessable entity for invalid seconds format' do + patch :set_timer_end, params: { id: @tournament.id, timer_end_seconds: 'invalid' } expect(response).to have_http_status(:unprocessable_entity) - expect(JSON.parse(response.body)).to include('error' => 'Invalid datetime format') + expect(JSON.parse(response.body)).to include('error' => 'Invalid seconds format') end - end - context 'when timer_end is in the past' do - it 'returns unprocessable entity' do - patch :set_timer_end, params: { id: @tournament.id, timer_end: 1.day.ago } + it 'returns unprocessable entity for negative seconds' do + patch :set_timer_end, params: { id: @tournament.id, timer_end_seconds: -3600 } expect(response).to have_http_status(:unprocessable_entity) expect(JSON.parse(response.body)).to include('error' => 'Timer end must be in the future') end - end - context 'when timer_end is valid' do - it 'updates the timer_end' do - valid_timer_end = 1.day.from_now.change(usec: 0) - patch :set_timer_end, params: { id: @tournament.id, timer_end: valid_timer_end } + it 'updates the timer_end with valid seconds' do + valid_timer_end_seconds = 3600 + expected_timer_end = (Time.zone.now + valid_timer_end_seconds).change(usec: 0) + patch :set_timer_end, params: { id: @tournament.id, timer_end_seconds: valid_timer_end_seconds } expect(response).to have_http_status(:ok) - expect(@tournament.reload.timer_end).to eq(valid_timer_end) + expect(@tournament.reload.timer_end.change(usec: 0)).to eq(expected_timer_end) + end + end + context 'when both timer_end and timer_end_seconds are provided' do + it 'returns unprocessable entity' do + patch :set_timer_end, params: { id: @tournament.id, timer_end: 1.day.from_now, timer_end_seconds: 3600 } + expect(response).to have_http_status(:unprocessable_entity) + expect(JSON.parse(response.body)).to include('error' => 'Only one of timer_end or timer_end_seconds is allowed') end end end