From e957c00866a353168bd50eebb3b3b6d2afceef95 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Tue, 27 Oct 2026 13:14:06 +0100 Subject: [PATCH] refactor: run the redirect simulation over a rule list CheckRedirect loads the stored rules and hands them to checkRedirectRules, which needs no database, so the loop and chain rules can be unit-tested. No behaviour change. --- classes/redirect_graph.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/classes/redirect_graph.go b/classes/redirect_graph.go index cd4b815..c253cbc 100644 --- a/classes/redirect_graph.go +++ b/classes/redirect_graph.go @@ -166,13 +166,22 @@ func classHas(ranges []rune, c rune) bool { // chain when it takes more than one hop or when another rule's target // leads into r. A 410 rule ends every chain and is never a loop. func (s *Service) CheckRedirect(ctx context.Context, db *gorm.DB, r models.Redirect) (RedirectCheck, error) { - var check RedirectCheck if r.Status == models.Status410 { - return check, nil + return RedirectCheck{}, nil } rules, err := LoadRedirects(db.WithContext(ctx)) if err != nil { - return check, err + return RedirectCheck{}, err + } + return checkRedirectRules(s.SiteURL(), rules, r) +} + +// checkRedirectRules is CheckRedirect over the stored rules given, for the +// site URL site. +func checkRedirectRules(site string, rules []models.Redirect, r models.Redirect) (RedirectCheck, error) { + var check RedirectCheck + if r.Status == models.Status410 { + return check, nil } if r.ID == 0 { r.ID = candidateID @@ -187,7 +196,6 @@ func (s *Service) CheckRedirect(ctx context.Context, db *gorm.DB, r models.Redir rules = append(rules, r) } set := NewRedirectSet(rules) - site := s.SiteURL() path, query, ok := redirectProbe(r) if ok { ch, err := set.Follow(site, path, query, MaxRedirectHops)