1
0
mirror of https://github.com/jcwimer/wrestlingApp synced 2026-04-06 14:36:59 +00:00

Fixed reset password after the Devise migration.

This commit is contained in:
2025-04-14 14:25:40 -04:00
parent 4828d9b876
commit 01a499cc45
18 changed files with 383 additions and 158 deletions

3
.cursorrules Normal file
View File

@@ -0,0 +1,3 @@
- If rails isn't installed use docker: docker run -it -v $(pwd):/rails wrestlingdev-dev <rails command>
- If the docker image doesn't exist, use the build command: docker build -t wrestlingdev-dev -f deploy/rails-dev-Dockerfile .
- If the Gemfile changes, you need to rebuild the docker image: docker build -t wrestlingdev-dev -f deploy/rails-dev-Dockerfile .

View File

@@ -173,24 +173,4 @@ SolidQueue plugin enabled in Puma
See `SOLID_QUEUE.md` for details about the job system configuration. See `SOLID_QUEUE.md` for details about the job system configuration.
# AI Assistant Note
<!--
This section contains information specifically for AI code assistants to help understand the codebase structure:
1. Project type: Rails 8 application for managing wrestling tournaments
2. Key components:
- Database: MySQL/MariaDB in production, SQLite in development
- Background jobs: SolidQueue running in Puma (SOLID_QUEUE_IN_PUMA=true)
- Multiple databases: One each for main app, queue, cache, and cable
3. Development paths:
- Docker-based: Primary method using deploy/rails-dev-Dockerfile
- RVM-based: Alternative for local development
4. Important services:
- Tournament management (tournaments, matches, wrestlers)
- Background job processing (SolidQueue)
- User authentication (Devise)
5. Deployment: Kubernetes-based with environment variables
-->
This project provides multiple ways to develop and deploy, with Docker being the primary method. This project provides multiple ways to develop and deploy, with Docker being the primary method.

View File

@@ -9,8 +9,31 @@ class AdvanceWrestlerJob < ApplicationJob
end end
def perform(wrestler, match) def perform(wrestler, match)
# Execute the job # Get tournament from wrestler
service = AdvanceWrestler.new(wrestler, match) tournament = wrestler.tournament
service.advance_raw
# Create job status record
job_name = "Advancing wrestler #{wrestler.name}"
job_status = TournamentJobStatus.create!(
tournament: tournament,
job_name: job_name,
status: "Running",
details: "Match ID: #{match.bout_number}"
)
begin
# Execute the job
service = AdvanceWrestler.new(wrestler, match)
service.advance_raw
# Remove the job status record on success
TournamentJobStatus.complete_job(tournament.id, job_name)
rescue => e
# Update status to errored
job_status.update(status: "Errored", details: "Error: #{e.message}")
# Re-raise the error for SolidQueue to handle
raise e
end
end end
end end

View File

@@ -11,7 +11,28 @@ class CalculateSchoolScoreJob < ApplicationJob
# Log information about the job # Log information about the job
Rails.logger.info("Calculating score for school ##{school.id} (#{school.name})") Rails.logger.info("Calculating score for school ##{school.id} (#{school.name})")
# Execute the calculation # Create job status record
school.calculate_score_raw tournament = school.tournament
job_name = "Calculating team score for #{school.name}"
job_status = TournamentJobStatus.create!(
tournament: tournament,
job_name: job_name,
status: "Running",
details: "School ID: #{school.id}"
)
begin
# Execute the calculation
school.calculate_score_raw
# Remove the job status record on success
TournamentJobStatus.complete_job(tournament.id, job_name)
rescue => e
# Update status to errored
job_status.update(status: "Errored", details: "Error: #{e.message}")
# Re-raise the error for SolidQueue to handle
raise e
end
end end
end end

View File

@@ -12,8 +12,28 @@ class TournamentBackupJob < ApplicationJob
# Log information about the job # Log information about the job
Rails.logger.info("Creating backup for tournament ##{tournament.id} (#{tournament.name}), reason: #{reason || 'manual'}") Rails.logger.info("Creating backup for tournament ##{tournament.id} (#{tournament.name}), reason: #{reason || 'manual'}")
# Execute the backup # Create job status record
service = TournamentBackupService.new(tournament, reason) job_name = "Backing up tournament"
service.create_backup_raw job_status = TournamentJobStatus.create!(
tournament: tournament,
job_name: job_name,
status: "Running",
details: "Reason: #{reason || 'manual'}"
)
begin
# Execute the backup
service = TournamentBackupService.new(tournament, reason)
service.create_backup_raw
# Remove the job status record on success
TournamentJobStatus.complete_job(tournament.id, job_name)
rescue => e
# Update status to errored
job_status.update(status: "Errored", details: "Error: #{e.message}")
# Re-raise the error for SolidQueue to handle
raise e
end
end end
end end

View File

@@ -13,9 +13,29 @@ class WrestlingdevImportJob < ApplicationJob
# Log information about the job # Log information about the job
Rails.logger.info("Starting import for tournament ##{tournament.id} (#{tournament.name})") Rails.logger.info("Starting import for tournament ##{tournament.id} (#{tournament.name})")
# Execute the import # Create job status record
importer = WrestlingdevImporter.new(tournament) job_name = "Importing tournament"
importer.import_data = import_data if import_data job_status = TournamentJobStatus.create!(
importer.import_raw tournament: tournament,
job_name: job_name,
status: "Running",
details: "Processing backup data"
)
begin
# Execute the import
importer = WrestlingdevImporter.new(tournament)
importer.import_data = import_data if import_data
importer.import_raw
# Remove the job status record on success
TournamentJobStatus.complete_job(tournament.id, job_name)
rescue => e
# Update status to errored
job_status.update(status: "Errored", details: "Error: #{e.message}")
# Re-raise the error for SolidQueue to handle
raise e
end
end end
end end

View File

@@ -9,6 +9,7 @@ class Tournament < ApplicationRecord
has_many :delegates, class_name: "TournamentDelegate" has_many :delegates, class_name: "TournamentDelegate"
has_many :mat_assignment_rules, dependent: :destroy has_many :mat_assignment_rules, dependent: :destroy
has_many :tournament_backups, dependent: :destroy has_many :tournament_backups, dependent: :destroy
has_many :tournament_job_statuses, dependent: :destroy
validates :date, :name, :tournament_type, :address, :director, :director_email , presence: true validates :date, :name, :tournament_type, :address, :director, :director_email , presence: true
@@ -263,6 +264,16 @@ class Tournament < ApplicationRecord
return error_string.blank? return error_string.blank?
end end
# Check if there are any active jobs for this tournament
def has_active_jobs?
tournament_job_statuses.active.exists?
end
# Get all active jobs for this tournament
def active_jobs
tournament_job_statuses.active
end
private private
def connection_adapter def connection_adapter

View File

@@ -0,0 +1,20 @@
class TournamentJobStatus < ApplicationRecord
belongs_to :tournament
# Validations
validates :job_name, presence: true
validates :status, presence: true, inclusion: { in: ["Queued", "Running", "Errored"] }
# Scopes
scope :active, -> { where.not(status: "Errored") }
# Class methods to find jobs for a tournament
def self.for_tournament(tournament)
where(tournament_id: tournament.id)
end
# Clean up completed jobs (should be called when job finishes successfully)
def self.complete_job(tournament_id, job_name)
where(tournament_id: tournament_id, job_name: job_name).destroy_all
end
end

View File

@@ -9,6 +9,19 @@
</div> </div>
<% end %> <% end %>
<% if (can? :manage, @tournament) && @tournament.has_active_jobs? %>
<div class="alert alert-info">
<strong>Background Jobs In Progress</strong>
<p>The following background jobs are currently running:</p>
<ul>
<% @tournament.active_jobs.each do |job| %>
<li><%= job.job_name %> - <%= job.status %> <%= "(#{job.details})" if job.details.present? %></li>
<% end %>
</ul>
<p>Please refresh the page to check progress.</p>
</div>
<% end %>
<p> <p>
<strong>Address:</strong> <strong>Address:</strong>
<%= @tournament.address %> <%= @tournament.address %>

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do ActiveRecord::Schema[8.0].define(version: 2025_04_11_183818) do
create_table "mat_assignment_rules", force: :cascade do |t| create_table "mat_assignment_rules", force: :cascade do |t|
t.integer "tournament_id", null: false t.integer "tournament_id", null: false
t.integer "mat_id", null: false t.integer "mat_id", null: false
@@ -242,6 +242,17 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
t.datetime "updated_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false
end end
create_table "tournament_job_statuses", force: :cascade do |t|
t.integer "tournament_id", null: false
t.string "job_name", null: false
t.string "status", default: "Queued", null: false
t.text "details"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["tournament_id", "job_name"], name: "index_tournament_job_statuses_on_tournament_id_and_job_name"
t.index ["tournament_id"], name: "index_tournament_job_statuses_on_tournament_id"
end
create_table "tournaments", force: :cascade do |t| create_table "tournaments", force: :cascade do |t|
t.string "name" t.string "name"
t.string "address" t.string "address"
@@ -312,4 +323,5 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "tournament_job_statuses", "tournaments"
end end

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do ActiveRecord::Schema[8.0].define(version: 2025_04_11_183818) do
create_table "mat_assignment_rules", force: :cascade do |t| create_table "mat_assignment_rules", force: :cascade do |t|
t.integer "tournament_id", null: false t.integer "tournament_id", null: false
t.integer "mat_id", null: false t.integer "mat_id", null: false
@@ -242,6 +242,17 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
t.datetime "updated_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false
end end
create_table "tournament_job_statuses", force: :cascade do |t|
t.integer "tournament_id", null: false
t.string "job_name", null: false
t.string "status", default: "Queued", null: false
t.text "details"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["tournament_id", "job_name"], name: "index_tournament_job_statuses_on_tournament_id_and_job_name"
t.index ["tournament_id"], name: "index_tournament_job_statuses_on_tournament_id"
end
create_table "tournaments", force: :cascade do |t| create_table "tournaments", force: :cascade do |t|
t.string "name" t.string "name"
t.string "address" t.string "address"
@@ -312,4 +323,5 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "tournament_job_statuses", "tournaments"
end end

View File

@@ -0,0 +1,13 @@
class CreateTournamentJobStatuses < ActiveRecord::Migration[8.0]
def change
create_table :tournament_job_statuses do |t|
t.references :tournament, null: false, foreign_key: true
t.string :job_name, null: false
t.string :status, null: false, default: "Queued" # Queued, Running, Errored
t.text :details # Additional details about the job (e.g., wrestler name, school name)
t.timestamps
end
add_index :tournament_job_statuses, [:tournament_id, :job_name]
end
end

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do ActiveRecord::Schema[8.0].define(version: 2025_04_11_183818) do
create_table "mat_assignment_rules", force: :cascade do |t| create_table "mat_assignment_rules", force: :cascade do |t|
t.integer "tournament_id", null: false t.integer "tournament_id", null: false
t.integer "mat_id", null: false t.integer "mat_id", null: false
@@ -242,6 +242,17 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
t.datetime "updated_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false
end end
create_table "tournament_job_statuses", force: :cascade do |t|
t.integer "tournament_id", null: false
t.string "job_name", null: false
t.string "status", default: "Queued", null: false
t.text "details"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["tournament_id", "job_name"], name: "index_tournament_job_statuses_on_tournament_id_and_job_name"
t.index ["tournament_id"], name: "index_tournament_job_statuses_on_tournament_id"
end
create_table "tournaments", force: :cascade do |t| create_table "tournaments", force: :cascade do |t|
t.string "name" t.string "name"
t.string "address" t.string "address"
@@ -312,4 +323,5 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "tournament_job_statuses", "tournaments"
end end

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do ActiveRecord::Schema[8.0].define(version: 2025_04_11_183818) do
create_table "mat_assignment_rules", force: :cascade do |t| create_table "mat_assignment_rules", force: :cascade do |t|
t.integer "tournament_id", null: false t.integer "tournament_id", null: false
t.integer "mat_id", null: false t.integer "mat_id", null: false
@@ -242,6 +242,17 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
t.datetime "updated_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false
end end
create_table "tournament_job_statuses", force: :cascade do |t|
t.integer "tournament_id", null: false
t.string "job_name", null: false
t.string "status", default: "Queued", null: false
t.text "details"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["tournament_id", "job_name"], name: "index_tournament_job_statuses_on_tournament_id_and_job_name"
t.index ["tournament_id"], name: "index_tournament_job_statuses_on_tournament_id"
end
create_table "tournaments", force: :cascade do |t| create_table "tournaments", force: :cascade do |t|
t.string "name" t.string "name"
t.string "address" t.string "address"
@@ -312,4 +323,5 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_05_160115) do
add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "tournament_job_statuses", "tournaments"
end end

View File

@@ -1,122 +0,0 @@
require 'test_helper'
class PasswordResetsControllerTest < ActionController::TestCase
def setup
@user = users(:one)
@user.email = 'user@example.com'
@user.password_digest = BCrypt::Password.create('password')
@user.save
end
test "should get new" do
get :new
assert_response :success
assert_select 'h1', 'Forgot password'
end
test "should not create password reset with invalid email" do
post :create, params: { password_reset: { email: 'invalid@example.com' } }
assert_template 'new'
assert_not_nil flash[:alert]
end
# Skip this test as it requires a working mailer setup
test "should create password reset" do
skip "Skipping as it requires a working mailer setup"
post :create, params: { password_reset: { email: @user.email } }
assert_redirected_to root_path
assert_not_nil flash[:notice]
@user.reload
assert_not_nil @user.reset_digest
assert_not_nil @user.reset_sent_at
end
# Skip this test as it requires a working reset token
test "should get edit with valid token" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.save
get :edit, params: { id: @user.reset_token, email: @user.email }
assert_response :success
assert_select "input[name='email'][type='hidden'][value='#{@user.email}']"
end
# Skip this test as it requires a working reset token
test "should not get edit with invalid token" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.save
get :edit, params: { id: 'wrong_token', email: @user.email }
assert_redirected_to root_path
end
# Skip this test as it requires a working reset token
test "should not get edit with invalid email" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.save
get :edit, params: { id: @user.reset_token, email: 'wrong@example.com' }
assert_redirected_to root_path
end
# Skip this test as it requires a working reset token
test "should not get edit with expired token" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.reset_sent_at = 3.hours.ago
@user.save
get :edit, params: { id: @user.reset_token, email: @user.email }
assert_redirected_to new_password_reset_path
assert_not_nil flash[:alert]
end
# Skip this test as it requires a working reset token
test "should update password with valid information" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.save
patch :update, params: {
id: @user.reset_token,
email: @user.email,
user: {
password: 'newpassword',
password_confirmation: 'newpassword'
}
}
assert_redirected_to root_path
assert_not_nil flash[:notice]
@user.reload
end
# Skip this test as it requires a working reset token
test "should not update password with invalid password confirmation" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.save
patch :update, params: {
id: @user.reset_token,
email: @user.email,
user: {
password: 'newpassword',
password_confirmation: 'wrongconfirmation'
}
}
assert_template 'edit'
end
# Skip this test as it requires a working reset token
test "should not update password with empty password" do
skip "Skipping as it requires a working reset token"
@user.create_reset_digest
@user.save
patch :update, params: {
id: @user.reset_token,
email: @user.email,
user: {
password: '',
password_confirmation: ''
}
}
assert_template 'edit'
end
end

View File

@@ -0,0 +1,35 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the "{}" from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value
queued_job:
tournament: one
job_name: "Test Queued Job"
status: "Queued"
details: "Test job details"
running_job:
tournament: one
job_name: "Test Running Job"
status: "Running"
details: "Test running job details"
errored_job:
tournament: one
job_name: "Test Errored Job"
status: "Errored"
details: "Test error message"
another_tournament_job:
tournament: two
job_name: "Another Tournament Job"
status: "Running"
details: "Different tournament test"

View File

@@ -0,0 +1,70 @@
require "test_helper"
class TournamentJobStatusIntegrationTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
setup do
@tournament = tournaments(:one)
@user = users(:admin) # Assuming an admin user exists in your fixtures
@running_job = tournament_job_statuses(:running_job)
@errored_job = tournament_job_statuses(:errored_job)
sign_in @user
end
test "tournament director sees active jobs on tournament show page" do
get tournament_path(@tournament)
assert_response :success
# Should display the running job but not the errored job
assert_match @running_job.job_name, response.body
assert_match "Background Jobs In Progress", response.body
assert_no_match @errored_job.job_name, response.body
end
test "tournament director does not see job section when no active jobs" do
# Delete all active jobs
TournamentJobStatus.where.not(status: "Errored").destroy_all
get tournament_path(@tournament)
assert_response :success
# Should not display the job section
assert_no_match "Background Jobs In Progress", response.body
end
test "non-director user does not see job information" do
sign_out @user
@regular_user = users(:one) # Assuming a regular user exists in fixtures
sign_in @regular_user
# Assuming regular users don't have permission to manage the tournament
get tournament_path(@tournament)
assert_response :success
# Should not display job information
assert_no_match "Background Jobs In Progress", response.body
end
test "jobs get cleaned up after successful completion" do
# Test that CalculateSchoolScoreJob removes job status when complete
school = schools(:one)
job_name = "Calculating team score for #{school.name}"
# Create a job status for this school
TournamentJobStatus.create!(
tournament: @tournament,
job_name: job_name,
status: "Running"
)
# Verify the job exists
assert TournamentJobStatus.exists?(tournament: @tournament, job_name: job_name)
# Run the job synchronously
CalculateSchoolScoreJob.perform_sync(school)
# Verify the job status was removed
assert_not TournamentJobStatus.exists?(tournament: @tournament, job_name: job_name)
end
end

View File

@@ -0,0 +1,70 @@
require "test_helper"
class TournamentJobStatusTest < ActiveSupport::TestCase
setup do
@tournament = tournaments(:one)
@job_status = tournament_job_statuses(:running_job)
end
test "should be valid with required fields" do
job_status = TournamentJobStatus.new(
tournament: @tournament,
job_name: "Test Job",
status: "Queued"
)
assert job_status.valid?
end
test "should require tournament" do
@job_status.tournament = nil
assert_not @job_status.valid?
end
test "should require job_name" do
@job_status.job_name = nil
assert_not @job_status.valid?
end
test "should require status" do
@job_status.status = nil
assert_not @job_status.valid?
end
test "status should be one of the allowed values" do
@job_status.status = "Invalid Status"
assert_not @job_status.valid?
@job_status.status = "Queued"
assert @job_status.valid?
@job_status.status = "Running"
assert @job_status.valid?
@job_status.status = "Errored"
assert @job_status.valid?
end
test "active scope should exclude errored jobs" do
active_jobs = TournamentJobStatus.active
assert_includes active_jobs, tournament_job_statuses(:queued_job)
assert_includes active_jobs, tournament_job_statuses(:running_job)
assert_not_includes active_jobs, tournament_job_statuses(:errored_job)
end
test "for_tournament should return only jobs for a specific tournament" do
tournament_one_jobs = TournamentJobStatus.for_tournament(@tournament)
assert_equal 3, tournament_one_jobs.count
assert_includes tournament_one_jobs, tournament_job_statuses(:queued_job)
assert_includes tournament_one_jobs, tournament_job_statuses(:running_job)
assert_includes tournament_one_jobs, tournament_job_statuses(:errored_job)
assert_not_includes tournament_one_jobs, tournament_job_statuses(:another_tournament_job)
end
test "complete_job should remove jobs with matching tournament_id and job_name" do
assert_difference 'TournamentJobStatus.count', -1 do
TournamentJobStatus.complete_job(@tournament.id, "Test Running Job")
end
assert_nil TournamentJobStatus.find_by(id: @job_status.id)
end
end