mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01:00
fix: return 404 if the project doesn't exist (#8362)
This change adds a check for whether the project exists in the database before trying to fetch data for it. If it doesn't exist, you'll get a 404.
This commit is contained in:
parent
1875c9b6d1
commit
2ac9c701c3
@ -19,9 +19,7 @@ export class FakeOnboardingReadModel implements IOnboardingReadModel {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
getOnboardingStatusForProject(
|
||||
projectId: string,
|
||||
): Promise<OnboardingStatus> {
|
||||
throw new Error('Method not implemented.');
|
||||
async getOnboardingStatusForProject(): Promise<OnboardingStatus | null> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -26,5 +26,7 @@ export type ProjectOnboarding = {
|
||||
export interface IOnboardingReadModel {
|
||||
getInstanceOnboardingMetrics(): Promise<InstanceOnboarding>;
|
||||
getProjectsOnboardingMetrics(): Promise<Array<ProjectOnboarding>>;
|
||||
getOnboardingStatusForProject(projectId: string): Promise<OnboardingStatus>;
|
||||
getOnboardingStatusForProject(
|
||||
projectId: string,
|
||||
): Promise<OnboardingStatus | null>;
|
||||
}
|
||||
|
@ -82,7 +82,16 @@ export class OnboardingReadModel implements IOnboardingReadModel {
|
||||
|
||||
async getOnboardingStatusForProject(
|
||||
projectId: string,
|
||||
): Promise<OnboardingStatus> {
|
||||
): Promise<OnboardingStatus | null> {
|
||||
const projectExists = await this.db('projects')
|
||||
.select(1)
|
||||
.where('id', projectId)
|
||||
.first();
|
||||
|
||||
if (!projectExists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const feature = await this.db('features')
|
||||
.select('name')
|
||||
.where('project', projectId)
|
||||
|
@ -335,6 +335,14 @@ test('should return personal dashboard project details', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("should return 404 if the project doesn't exist", async () => {
|
||||
await loginUser('new_user@test.com');
|
||||
|
||||
await app.request
|
||||
.get(`/api/admin/personal-dashboard/${randomId()}`)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
test('should return Unleash admins', async () => {
|
||||
await loginUser('new_user@test.com');
|
||||
const adminRoleId = 1;
|
||||
|
@ -21,6 +21,7 @@ import type { FeatureEventFormatter } from '../../addons/feature-event-formatter
|
||||
import { generateImageUrl } from '../../util';
|
||||
import type { PersonalDashboardProjectDetailsSchema } from '../../openapi';
|
||||
import type { IRoleWithProject } from '../../types/stores/access-store';
|
||||
import { NotFoundError } from '../../error';
|
||||
|
||||
export class PersonalDashboardService {
|
||||
private personalDashboardReadModel: IPersonalDashboardReadModel;
|
||||
@ -105,6 +106,17 @@ export class PersonalDashboardService {
|
||||
userId: number,
|
||||
projectId: string,
|
||||
): Promise<PersonalDashboardProjectDetailsSchema> {
|
||||
const onboardingStatus =
|
||||
await this.onboardingReadModel.getOnboardingStatusForProject(
|
||||
projectId,
|
||||
);
|
||||
|
||||
if (!onboardingStatus) {
|
||||
throw new NotFoundError(
|
||||
`No project with id "${projectId}" exists.`,
|
||||
);
|
||||
}
|
||||
|
||||
const formatEvents = (recentEvents: IEvent[]) =>
|
||||
recentEvents.map((event) => ({
|
||||
summary: this.featureEventFormatter.format(event).text,
|
||||
@ -122,29 +134,22 @@ export class PersonalDashboardService {
|
||||
type: role.type as PersonalDashboardProjectDetailsSchema['roles'][number]['type'],
|
||||
}));
|
||||
|
||||
const [latestEvents, onboardingStatus, owners, roles, healthScores] =
|
||||
await Promise.all([
|
||||
this.eventStore
|
||||
.searchEvents({ limit: 4, offset: 0 }, [
|
||||
{
|
||||
field: 'project',
|
||||
operator: 'IS',
|
||||
values: [projectId],
|
||||
},
|
||||
])
|
||||
.then(formatEvents),
|
||||
this.onboardingReadModel.getOnboardingStatusForProject(
|
||||
projectId,
|
||||
),
|
||||
this.projectOwnersReadModel.getProjectOwners(projectId),
|
||||
this.accessStore
|
||||
.getAllProjectRolesForUser(userId, projectId)
|
||||
.then(filterRoles),
|
||||
this.personalDashboardReadModel.getLatestHealthScores(
|
||||
projectId,
|
||||
8,
|
||||
),
|
||||
]);
|
||||
const [latestEvents, owners, roles, healthScores] = await Promise.all([
|
||||
this.eventStore
|
||||
.searchEvents({ limit: 4, offset: 0 }, [
|
||||
{
|
||||
field: 'project',
|
||||
operator: 'IS',
|
||||
values: [projectId],
|
||||
},
|
||||
])
|
||||
.then(formatEvents),
|
||||
this.projectOwnersReadModel.getProjectOwners(projectId),
|
||||
this.accessStore
|
||||
.getAllProjectRolesForUser(userId, projectId)
|
||||
.then(filterRoles),
|
||||
this.personalDashboardReadModel.getLatestHealthScores(projectId, 8),
|
||||
]);
|
||||
|
||||
let avgHealthCurrentWindow: number | null = null;
|
||||
let avgHealthPastWindow: number | null = null;
|
||||
|
@ -1546,7 +1546,9 @@ export default class ProjectService {
|
||||
updatedAt: project.updatedAt,
|
||||
archivedAt: project.archivedAt,
|
||||
createdAt: project.createdAt,
|
||||
onboardingStatus,
|
||||
onboardingStatus: onboardingStatus ?? {
|
||||
status: 'onboarding-started',
|
||||
},
|
||||
environments,
|
||||
featureTypeCounts,
|
||||
members,
|
||||
|
Loading…
Reference in New Issue
Block a user