Răsfoiți Sursa

Route every alias of a post, not only its first

DataModule::aliases() did @aliases{ @{ $post->{aliases} } } = $post->{local_href},
and assigning one value to a hash slice fills only its first key.  So every
alias after a post's first mapped to undef.  A series always has two,
/posts/$id and /series/$id, so every fresh tPSGI worker logged an
uninitialized value for each series while it registered the aliases.  It
has been this way since aliases were added.

The SQLite model uses this sub.  FlatFile answers from its tag index,
which stores one row per alias and was right.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
George Baugh 1 săptămână în urmă
părinte
comite
804581b84e
2 a modificat fișierele cu 22 adăugiri și 1 ștergeri
  1. 1 1
      lib/Trog/DataModule.pm
  2. 21 0
      t/Trog-Data-SQLite.t

+ 1 - 1
lib/Trog/DataModule.pm

@@ -1008,7 +1008,7 @@ sub aliases ($self) {
     my @posts = $self->get( limit => 0, acls => ['admin'] );
     my %aliases;
     foreach my $post (@posts) {
-        @aliases{ @{ $post->{aliases} } } = $post->{local_href};
+        $aliases{$_} = $post->{local_href} for @{ $post->{aliases} // [] };
     }
     return %aliases;
 }

+ 21 - 0
t/Trog-Data-SQLite.t

@@ -455,4 +455,25 @@ subtest 'indexing a custom field' => sub {
     ok( !$indexes->()->{'posts_custom_post_data'}, 'and a schema column did not pick up an index of its own' );
 };
 
+# Last, so the post it adds changes no count asserted above.
+subtest 'aliases' => sub {
+    my $aliased = post(
+        id         => 'p-aliased',
+        title      => 'Many Names',
+        local_href => '/posts/p-aliased',
+        method     => 'GET',
+        callback   => 'Trog::Routes::HTML::posts',
+        aliases    => [qw{/one /two /three}],
+    );
+    $sqlite->write( [ { %$aliased, tags => [ @{ $aliased->{tags} } ] } ] );
+    $flat->write( [ { %$aliased, tags => [ @{ $aliased->{tags} } ] } ] );
+
+    my %want = map { $_ => '/posts/p-aliased' } qw{/one /two /three};
+    foreach my $case ( [ flatfile => $flat ], [ sqlite => $sqlite ] ) {
+        my ( $name, $model ) = @$case;
+        my %got = $model->aliases();
+        is_deeply( { map { $_ => $got{$_} } grep { exists $want{$_} } keys %got }, \%want, "$name: every alias of a post leads to it, not only the first" );
+    }
+};
+
 done_testing();