1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

feat: revive project (#7847)

This commit is contained in:
Mateusz Kwasniewski 2024-08-13 10:25:42 +02:00 committed by GitHub
parent fcf1329816
commit bb30032f2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 0 deletions

View File

@ -308,6 +308,30 @@ test('should archive project', async () => {
expect(projects.length).not.toBe(0);
});
test('should revive project', async () => {
const project = {
id: 'test-revive',
name: 'New project',
description: 'Blah',
mode: 'open' as const,
defaultStickiness: 'default',
};
await projectService.createProject(project, user, TEST_AUDIT_USER);
await projectService.archiveProject(project.id, TEST_AUDIT_USER);
await projectService.reviveProject(project.id, TEST_AUDIT_USER);
const events = await stores.eventStore.getEvents();
expect(events[0]).toMatchObject({
type: 'project-revived',
createdBy: TEST_AUDIT_USER.username,
});
const projects = await projectService.getProjects();
expect(projects.find((p) => p.id === project.id)).toMatchObject(project);
});
test('should not be able to archive project with flags', async () => {
const project = {
id: 'test-archive-with-flags',

View File

@ -47,6 +47,7 @@ import {
ProjectGroupAddedEvent,
ProjectGroupRemovedEvent,
ProjectGroupUpdateRoleEvent,
ProjectRevivedEvent,
ProjectUpdatedEvent,
ProjectUserAddedEvent,
ProjectUserRemovedEvent,
@ -625,6 +626,17 @@ export default class ProjectService {
);
}
async reviveProject(id: string, auditUser: IAuditUser): Promise<void> {
await this.projectStore.revive(id);
await this.eventService.storeEvent(
new ProjectRevivedEvent({
project: id,
auditUser,
}),
);
}
async validateId(id: string): Promise<boolean> {
await nameType.validateAsync(id);
await this.validateUniqueId(id);

View File

@ -138,4 +138,5 @@ export interface IProjectStore extends Store<IProject, string> {
): Promise<IProjectApplications>;
archive(projectId: string): Promise<void>;
revive(projectId: string): Promise<void>;
}

View File

@ -420,6 +420,10 @@ class ProjectStore implements IProjectStore {
await this.db(TABLE).where({ id }).update({ archived_at: now });
}
async revive(id: string): Promise<void> {
await this.db(TABLE).where({ id }).update({ archived_at: null });
}
async getProjectLinksForEnvironments(
environments: string[],
): Promise<IEnvironmentProjectLink[]> {

View File

@ -82,6 +82,7 @@ export const PROJECT_CREATED = 'project-created' as const;
export const PROJECT_UPDATED = 'project-updated' as const;
export const PROJECT_DELETED = 'project-deleted' as const;
export const PROJECT_ARCHIVED = 'project-archived' as const;
export const PROJECT_REVIVED = 'project-revived' as const;
export const PROJECT_IMPORT = 'project-import' as const;
export const PROJECT_USER_ADDED = 'project-user-added' as const;
export const PROJECT_USER_REMOVED = 'project-user-removed' as const;
@ -251,6 +252,7 @@ export const IEventTypes = [
PROJECT_UPDATED,
PROJECT_DELETED,
PROJECT_ARCHIVED,
PROJECT_REVIVED,
PROJECT_IMPORT,
PROJECT_USER_ADDED,
PROJECT_USER_REMOVED,
@ -593,6 +595,18 @@ export class ProjectArchivedEvent extends BaseEvent {
}
}
export class ProjectRevivedEvent extends BaseEvent {
readonly project: string;
constructor(eventData: {
project: string;
auditUser: IAuditUser;
}) {
super(PROJECT_REVIVED, eventData.auditUser);
this.project = eventData.project;
}
}
export class RoleUpdatedEvent extends BaseEvent {
readonly data: any;
readonly preData: any;

View File

@ -234,4 +234,10 @@ export default class FakeProjectStore implements IProjectStore {
: project,
);
}
async revive(id: string): Promise<void> {
this.projects = this.projects.map((project) =>
project.id === id ? { ...project, archivedAt: null } : project,
);
}
}