Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
f1717c43
Commit
f1717c43
authored
Apr 23, 2024
by
Alejandro Celaya
Committed by
Alejandro Celaya
Apr 23, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Display error when loading dashboard auth token fails
parent
32b6aa5f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
101 additions
and
46 deletions
+101
-46
OpenDashboardMenuItem.tsx
src/sidebar/components/OpenDashboardMenuItem.tsx
+33
-14
OpenDashboardMenuItem-test.js
src/sidebar/components/test/OpenDashboardMenuItem-test.js
+68
-32
No files found.
src/sidebar/components/OpenDashboardMenuItem.tsx
View file @
f1717c43
import
{
useEffect
,
useState
}
from
'preact/hooks'
;
import
{
use
Callback
,
use
Effect
,
useState
}
from
'preact/hooks'
;
import
{
withServices
}
from
'../service-context'
;
import
type
{
DashboardService
}
from
'../services/dashboard'
;
import
type
{
ToastMessengerService
}
from
'../services/toast-messenger'
;
import
MenuItem
from
'./MenuItem'
;
export
type
OpenDashboardMenuItemProps
=
{
...
...
@@ -9,36 +10,54 @@ export type OpenDashboardMenuItemProps = {
// Injected
dashboard
:
DashboardService
;
toastMessenger
:
ToastMessengerService
;
};
function
OpenDashboardMenuItem
({
dashboard
,
isMenuOpen
,
toastMessenger
,
}:
OpenDashboardMenuItemProps
)
{
const
[
authToken
,
setAuthToken
]
=
useState
<
string
>
();
const
[
authTokenOrError
,
setAuthTokenOrError
]
=
useState
<
string
|
Error
>
();
// Token is loading until we get it or an error occurs
const
loading
=
!
authTokenOrError
;
const
onClick
=
useCallback
(()
=>
{
if
(
typeof
authTokenOrError
===
'string'
)
{
dashboard
.
open
(
authTokenOrError
);
return
;
}
if
(
authTokenOrError
)
{
toastMessenger
.
error
(
"Can't open dashboard: You must reload the page."
,
{
autoDismiss
:
false
,
});
}
},
[
authTokenOrError
,
dashboard
,
toastMessenger
]);
useEffect
(()
=>
{
// Fetch a new auth token every time the menu containing this item is open,
// to make sure we always have an up-to-date one
if
(
isMenuOpen
)
{
dashboard
.
getAuthToken
()
.
then
(
setAuthToken
)
.
catch
(
error
=>
console
.
warn
(
'An error occurred while getting auth token'
,
error
),
);
.
then
(
setAuthTokenOrError
)
.
catch
(
error
=>
{
console
.
warn
(
'An error occurred while getting auth token'
,
error
);
setAuthTokenOrError
(
error
);
});
}
// Discard previous token just before trying to fetch a new one
return
()
=>
setAuthToken
(
undefined
);
// Discard previous token
and error,
just before trying to fetch a new one
return
()
=>
setAuthToken
OrError
(
undefined
);
},
[
dashboard
,
isMenuOpen
]);
return
(
<
MenuItem
label=
"Open dashboard"
isDisabled=
{
!
authToken
}
onClick=
{
()
=>
authToken
&&
dashboard
.
open
(
authToken
)
}
/>
<
MenuItem
label=
"Open dashboard"
isDisabled=
{
loading
}
onClick=
{
onClick
}
/>
);
}
export
default
withServices
(
OpenDashboardMenuItem
,
[
'dashboard'
]);
export
default
withServices
(
OpenDashboardMenuItem
,
[
'dashboard'
,
'toastMessenger'
,
]);
src/sidebar/components/test/OpenDashboardMenuItem-test.js
View file @
f1717c43
...
...
@@ -6,12 +6,16 @@ import OpenDashboardMenuItem from '../OpenDashboardMenuItem';
describe
(
'OpenDashboardMenuItem'
,
()
=>
{
let
fakeDashboard
;
let
fakeToastMessenger
;
beforeEach
(()
=>
{
fakeDashboard
=
{
getAuthToken
:
sinon
.
stub
().
resolves
(
'auth_token'
),
open
:
sinon
.
stub
(),
};
fakeToastMessenger
=
{
error
:
sinon
.
stub
(),
};
});
function
createComponent
({
isMenuOpen
=
false
}
=
{})
{
...
...
@@ -19,10 +23,23 @@ describe('OpenDashboardMenuItem', () => {
<
OpenDashboardMenuItem
isMenuOpen
=
{
isMenuOpen
}
dashboard
=
{
fakeDashboard
}
toastMessenger
=
{
fakeToastMessenger
}
/>
,
);
}
async
function
createOpenComponent
()
{
const
wrapper
=
createComponent
({
isMenuOpen
:
true
});
// Wait for an enabled menu item, which means loading the auth token finished
await
waitFor
(()
=>
{
wrapper
.
update
();
return
wrapper
.
exists
(
'MenuItem[isDisabled=false]'
);
});
return
wrapper
;
}
context
(
'when menu is closed'
,
()
=>
{
it
(
'does not try to load auth token'
,
()
=>
{
createComponent
();
...
...
@@ -39,20 +56,11 @@ describe('OpenDashboardMenuItem', () => {
wrapper
.
find
(
'MenuItem'
).
props
().
onClick
();
assert
.
notCalled
(
fakeDashboard
.
open
);
assert
.
notCalled
(
fakeToastMessenger
.
error
);
});
});
context
(
'when menu is open'
,
()
=>
{
async
function
createOpenComponent
()
{
const
wrapper
=
createComponent
({
isMenuOpen
:
true
});
// Wait for an enabled menu item, which means the auth token was loaded
await
waitFor
(()
=>
wrapper
.
find
(
'MenuItem[isDisabled=false]'
));
wrapper
.
update
();
return
wrapper
;
}
it
(
'loads auth token'
,
async
()
=>
{
await
createOpenComponent
();
assert
.
called
(
fakeDashboard
.
getAuthToken
);
...
...
@@ -68,33 +76,61 @@ describe('OpenDashboardMenuItem', () => {
wrapper
.
find
(
'MenuItem'
).
props
().
onClick
();
assert
.
calledWith
(
fakeDashboard
.
open
,
'auth_token'
);
assert
.
notCalled
(
fakeToastMessenger
.
error
);
});
});
it
(
'logs error if getting auth token fails'
,
async
()
=>
{
const
error
=
new
Error
(
'Error loading auth token'
);
context
(
'when menu opening changes'
,
()
=>
{
it
(
'goes back to loading state'
,
async
()
=>
{
const
wrapper
=
await
createOpenComponent
();
assert
.
isFalse
(
wrapper
.
find
(
'MenuItem'
).
prop
(
'isDisabled'
));
wrapper
.
setProps
({
isMenuOpen
:
false
});
assert
.
isTrue
(
wrapper
.
find
(
'MenuItem'
).
prop
(
'isDisabled'
));
});
});
context
(
'when loading auth token fails'
,
()
=>
{
const
error
=
new
Error
(
'Error loading auth token'
);
beforeEach
(()
=>
{
fakeDashboard
.
getAuthToken
.
rejects
(
error
);
sinon
.
stub
(
console
,
'warn'
);
});
afterEach
(()
=>
console
.
warn
.
restore
());
it
(
'logs error if getting auth token fails'
,
async
()
=>
{
createOpenComponent
();
try
{
createOpenComponent
();
assert
.
called
(
fakeDashboard
.
getAuthToken
);
await
waitFor
(()
=>
{
const
{
lastCall
}
=
console
.
warn
;
if
(
!
lastCall
)
{
return
false
;
}
const
{
args
}
=
lastCall
;
return
(
args
[
0
]
===
'An error occurred while getting auth token'
&&
args
[
1
]
===
error
);
});
}
finally
{
console
.
warn
.
restore
();
}
assert
.
called
(
fakeDashboard
.
getAuthToken
);
await
waitFor
(()
=>
{
const
{
lastCall
}
=
console
.
warn
;
if
(
!
lastCall
)
{
return
false
;
}
const
{
args
}
=
lastCall
;
return
(
args
[
0
]
===
'An error occurred while getting auth token'
&&
args
[
1
]
===
error
);
});
});
it
(
'shows toast message when trying to open dashboard'
,
async
()
=>
{
const
wrapper
=
await
createOpenComponent
();
const
menuItem
=
wrapper
.
find
(
'MenuItem'
);
menuItem
.
props
().
onClick
();
assert
.
notCalled
(
fakeDashboard
.
open
);
assert
.
calledWith
(
fakeToastMessenger
.
error
,
"Can't open dashboard: You must reload the page."
,
{
autoDismiss
:
false
},
);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment