also looking at this
LSU's own coaching surface, and what auditing the site turned up
#12
86 files
+3943
-1190
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -14,9 +14,7 @@ const canonicalPath = "/lottery" | ||
| 14 | 14 | </section> |
| 15 | 15 | <section id="form" class="entry lsu-scope-lottery"> |
| 16 | 16 | <div class="entry-shell lsu-scope-lottery"> |
| 17 | <div class="form lsu-scope-lottery portal" data-lottery-portal data-lang="en" aria-live="polite"> | |
| 18 | <div class="lsu-scope-lottery portal-message">Loading account access…</div> | |
| 19 | </div> | |
| 17 | <RacePortal /> | |
| 20 | 18 | </div> |
| 21 | 19 | </section> |
| 22 | 20 | <section class="lsu-scope-lottery open-now section"> |
| @@ -106,5 +104,4 @@ const canonicalPath = "/lottery" | ||
| 106 | 104 | <br class="lsu-scope-lottery">Selection is by LSU team and a random draw. </p> |
| 107 | 105 | </div> |
| 108 | 106 | </section> |
| 109 | <section class="section"><div class="shell"><RacePortal /></div></section> | |
| 110 | 107 | @endsection |
| @@ -0,0 +1,48 @@ | ||
| 1 | import { describe, expect, it } from 'bun:test' | |
| 2 | import { resolve } from 'node:path' | |
| 3 | import { processDirectives } from '@stacksjs/stx' | |
| 4 | ||
| 5 | /** | |
| 6 | * The entry page's job is one form. It shipped with two: a placeholder that | |
| 7 | * read "Loading account access…" in the section the page calls #form, which | |
| 8 | * nothing ever replaced, and the working portal more than a thousand pixels | |
| 9 | * below it. Nothing errored, and the page looked like it was still loading. | |
| 10 | */ | |
| 11 | ||
| 12 | async function render(view: string): Promise<string> { | |
| 13 | const path = resolve(`resources/views/${view}.stx`) | |
| 14 | return processDirectives(await Bun.file(path).text(), {}, path, { | |
| 15 | enabled: true, | |
| 16 | cache: false, | |
| 17 | componentsDir: resolve('resources/components'), | |
| 18 | layoutsDir: resolve('resources/layouts'), | |
| 19 | partialsDir: resolve('resources/partials'), | |
| 20 | }, new Set()) | |
| 21 | } | |
| 22 | ||
| 23 | describe('the entry page', () => { | |
| 24 | it('puts the form in the section it calls the form', async () => { | |
| 25 | const html = await render('lottery') | |
| 26 | const form = html.slice(html.indexOf('id="form"')) | |
| 27 | ||
| 28 | expect(form.indexOf('race-portal')).toBeGreaterThan(-1) | |
| 29 | // Before the next section begins. | |
| 30 | expect(form.indexOf('race-portal')).toBeLessThan(form.indexOf('open-now')) | |
| 31 | }) | |
| 32 | ||
| 33 | it('has one portal, not a working one and a decorative one', async () => { | |
| 34 | const html = await render('lottery') | |
| 35 | expect([...html.matchAll(/class="race-portal"/g)]).toHaveLength(1) | |
| 36 | }) | |
| 37 | ||
| 38 | it('shows no loading state that nothing ever clears', async () => { | |
| 39 | const html = await render('lottery') | |
| 40 | ||
| 41 | expect(html).not.toContain('Loading account access') | |
| 42 | expect(html).not.toContain('data-lottery-portal') | |
| 43 | }) | |
| 44 | ||
| 45 | it('offers the same account on the profile page', async () => { | |
| 46 | expect(await render('profile')).toContain('race-portal') | |
| 47 | }) | |
| 48 | }) | |