Skip to content

Commit 9e08a0c

Browse files
committed
Show AppLoader on first paint before the license resolver kicks in
1 parent ec1d6c0 commit 9e08a0c

3 files changed

Lines changed: 25 additions & 7 deletions

File tree

resources/js/context/harbor-data-context.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ export function HarborDataProvider( { children }: { children: ReactNode } ) {
8383
}
8484

8585
const isLoading = RESOLVER_KEYS.some( ( key ) => result[ key ].isResolving && ! hasEverResolvedRef.current[ key ] );
86-
const isLicenseLoading = result.license.isResolving && ! hasEverResolvedRef.current.license;
86+
// True until the license resolver has settled its first cycle. Covers both
87+
// the IDLE pre-fetch frame and the RESOLVING in-flight frame, so the
88+
// welcome screen never flashes before the resolver has had a chance to
89+
// report whether a key exists.
90+
const isLicenseLoading = ! hasEverResolvedRef.current.license;
8791

8892
useEffect( () => {
8993
const found = findErrors( result );

tests/js/context/harbor-data-context.test.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ describe( 'HarborDataContext', () => {
7373
expect( captured!.isLicenseLoading ).toBe( false );
7474
} );
7575

76+
it( 'flags isLicenseLoading on first render before the resolver has started (IDLE)', () => {
77+
setResolvers( {
78+
license: { isResolving: false, hasResolved: false },
79+
} );
80+
81+
render( <HarborDataProvider><Probe /></HarborDataProvider> );
82+
83+
expect( captured!.isLicenseLoading ).toBe( true );
84+
} );
85+
7686
it( 'flags both loading flags while the license resolver is on its first pass', () => {
7787
setResolvers( {
7888
license: { isResolving: true, hasResolved: false },

tests/js/hooks/useWelcomeLicenseForm.test.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,17 @@ describe( 'pickWelcomeErrorMessage', () => {
135135
);
136136
}
137137

138-
it( 'appends the plugin-settings hint for lw-harbor-invalid-key', () => {
138+
it( 'returns a single canned message for lw-harbor-invalid-key', () => {
139139
const error = withCause( 'lw-harbor-invalid-key', 'License key not recognized.' );
140140
const result = pickWelcomeErrorMessage( error );
141141

142-
expect( result.startsWith( 'License key not recognized.' ) ).toBe( true );
142+
// The canned message discards the server text and directs the user
143+
// toward the plugin-settings path.
144+
expect( result ).toMatch( /We couldn't verify this key/ );
143145
expect( result ).toMatch( /non-unified license/ );
144146
expect( result ).toMatch( /plugin's own settings page/ );
147+
// The server's diagnostic is intentionally not surfaced.
148+
expect( result ).not.toMatch( /License key not recognized\./ );
145149
} );
146150

147151
it.each( [
@@ -170,13 +174,13 @@ describe( 'pickWelcomeErrorMessage', () => {
170174
expect( result ).not.toMatch( /non-unified license/ );
171175
} );
172176

173-
it( 'falls back to error.message when cause.message is whitespace', () => {
177+
it( 'returns the canned invalid-key message even when cause.message is whitespace', () => {
174178
const error = withCause( 'lw-harbor-invalid-key', ' ' );
175179
const result = pickWelcomeErrorMessage( error );
176180

177-
// The wrapper message is preserved, and the plugin-settings hint is
178-
// still appended because the server code matched.
179-
expect( result.startsWith( 'Liquid Web Software Manager failed to validate your license.' ) ).toBe( true );
181+
// Whitespace in the server message doesn't change anything — the
182+
// invalid-key branch returns the canned message regardless.
183+
expect( result ).toMatch( /We couldn't verify this key/ );
180184
expect( result ).toMatch( /plugin's own settings page/ );
181185
} );
182186
} );

0 commit comments

Comments
 (0)