Skip to content

Commit

Permalink
List sites by most recent audit checked_at date
Browse files Browse the repository at this point in the history
  • Loading branch information
goulvench committed Mar 4, 2025
1 parent 8e8b99a commit acc15bf
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 30 deletions.
2 changes: 1 addition & 1 deletion app/controllers/sites_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class SitesController < ApplicationController

# GET /sites
def index
@pagy, @sites = pagy Site.sort_by_audit_url.includes(:audit)
@pagy, @sites = pagy Site.sort_by_audit_date.includes(:audit)
end

# GET /sites/1
Expand Down
2 changes: 1 addition & 1 deletion app/models/audit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Audit < ApplicationRecord
"failed", # All checks failed
].index_by(&:itself), validate: true, default: :pending

scope :sort_by_newest, -> { order(created_at: :desc) }
scope :sort_by_newest, -> { order(checked_at: :desc) }
scope :sort_by_url, -> { order(Arel.sql("REGEXP_REPLACE(audits.url, '^https?://(www\.)?', '') ASC")) }
scope :past, -> { where.not(status: :pending) }

Expand Down
8 changes: 8 additions & 0 deletions app/models/site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ class Site < ApplicationRecord
.order("sites.id, sortable_url")
from(subquery, :sites).order(:sortable_url)
end
scope :sort_by_audit_date, -> do
joins("LEFT JOIN (
SELECT site_id, MAX(checked_at) as latest_check
FROM audits
GROUP BY site_id
) latest_audits ON sites.id = latest_audits.site_id")
.order("latest_audits.latest_check DESC NULLS LAST, sites.created_at DESC")
end

class << self
def find_or_create_by_url(attributes)
Expand Down
8 changes: 4 additions & 4 deletions spec/models/audit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
describe "scopes" do
before { site.audit.destroy }

it ".sort_by_newest returns audits in descending order by creation date" do
oldest = create(:audit, site:, created_at: 3.days.ago)
older = create(:audit, site:, created_at: 2.days.ago)
newer = create(:audit, site:, created_at: 1.day.ago)
it ".sort_by_newest returns audits in descending order by checked_at date" do
oldest = create(:audit, site:, checked_at: 3.days.ago)
older = create(:audit, site:, checked_at: 2.days.ago)
newer = create(:audit, site:, checked_at: 1.day.ago)

expect(described_class.sort_by_newest).to eq([newer, older, oldest])
end
Expand Down
58 changes: 34 additions & 24 deletions spec/models/site_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,47 @@
end
end

describe ".find_or_create_by_url" do
let(:http_url) { "http://example.com" }
describe "scopes" do
it ".sort_by_audit_date orders sites by their most recent audit checked_at date" do
site1 = build(:site, audits: [build(:audit, checked_at: 1.day.ago)]).tap(&:save)
site2 = build(:site, audits: [build(:audit, checked_at: 5.days.ago)]).tap(&:save)
site3 = build(:site, audits: [build(:audit, checked_at: 2.days.ago)]).tap(&:save)

context "when site with URL exists" do
let!(:existing_site) { described_class.create(url:) }
expect(described_class.sort_by_audit_date).to eq([site1, site3, site2])
end

it "returns existing site for exact URL match" do
expect(described_class.find_or_create_by_url(url:)).to eq(existing_site)
end
describe ".find_or_create_by_url" do
let(:http_url) { "http://example.com" }

it "returns existing site when only scheme differs" do
expect(described_class.find_or_create_by_url(url: http_url)).to eq(existing_site)
end
context "when site with URL exists" do
let!(:existing_site) { described_class.create(url:) }

it "finds site with historical URLs" do
new_url = "https://new-example.com"
existing_site.audits.create!(url: new_url)
it "returns existing site for exact URL match" do
expect(described_class.find_or_create_by_url(url:)).to eq(existing_site)
end

expect(described_class.find_or_create_by_url(url:)).to eq(existing_site)
expect(described_class.find_or_create_by_url(url: new_url)).to eq(existing_site)
it "returns existing site when only scheme differs" do
expect(described_class.find_or_create_by_url(url: http_url)).to eq(existing_site)
end

it "finds site with historical URLs" do
new_url = "https://new-example.com"
existing_site.audits.create!(url: new_url)

expect(described_class.find_or_create_by_url(url:)).to eq(existing_site)
expect(described_class.find_or_create_by_url(url: new_url)).to eq(existing_site)
end
end
end

context "when site does not exist" do
it "creates a new site with audit" do
expect {
site = described_class.find_or_create_by_url(url:)
expect(site).to be_persisted
expect(site.audit.url).to eq(url)
}.to change(described_class, :count).by(1)
.and change(Audit, :count).by(1)
context "when site does not exist" do
it "creates a new site with audit" do
expect {
site = described_class.find_or_create_by_url(url:)
expect(site).to be_persisted
expect(site.audit.url).to eq(url)
}.to change(described_class, :count).by(1)
.and change(Audit, :count).by(1)
end
end
end
end
Expand Down

0 comments on commit acc15bf

Please sign in to comment.