1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

feat: add user preference change to event log (#8652)

This commit is contained in:
Tymoteusz Czech 2024-11-05 15:52:11 +01:00 committed by GitHub
parent 7c192378d6
commit 7aa74cccd3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 97 additions and 24 deletions

View File

@ -1,7 +1,8 @@
import {
type IEventStore,
type IUnleashConfig,
type IUnleashStores,
type IUser,
type IUserStore,
TEST_AUDIT_USER,
} from '../../types';
import type { UserSubscriptionsService } from './user-subscriptions-service';
@ -13,25 +14,27 @@ import type { IUserSubscriptionsReadModel } from './user-subscriptions-read-mode
let stores: IUnleashStores;
let db: ITestDb;
let userStore: IUserStore;
let userSubscriptionService: UserSubscriptionsService;
let userSubscriptionsReadModel: IUserSubscriptionsReadModel;
let eventsStore: IEventStore;
let config: IUnleashConfig;
let user: IUser;
beforeAll(async () => {
db = await dbInit('user_subscriptions', getLogger);
stores = db.stores;
config = createTestConfig({});
userStore = stores.userStore;
userSubscriptionService = createUserSubscriptionsService(config)(
db.rawDatabase,
);
userSubscriptionsReadModel = db.stores.userSubscriptionsReadModel;
eventsStore = db.stores.eventStore;
});
user = await stores.userStore.insert({
email: 'test@getunleash.io',
name: 'Sample Name',
});
beforeEach(async () => {
await userStore.deleteAll();
});
afterAll(async () => {
@ -39,6 +42,11 @@ afterAll(async () => {
});
test('Subscribe and unsubscribe', async () => {
const user = await userStore.insert({
email: 'test@getunleash.io',
name: 'Sample Name',
});
const subscribers = await userSubscriptionsReadModel.getSubscribedUsers(
'productivity-report',
);
@ -47,7 +55,7 @@ test('Subscribe and unsubscribe', async () => {
]);
const userSubscriptions =
await userSubscriptionsReadModel.getUserSubscriptions(user.id);
await userSubscriptionService.getUserSubscriptions(user.id);
expect(userSubscriptions).toMatchObject(['productivity-report']);
await userSubscriptionService.unsubscribe(
@ -62,6 +70,49 @@ test('Subscribe and unsubscribe', async () => {
expect(noSubscribers).toMatchObject([]);
const noUserSubscriptions =
await userSubscriptionsReadModel.getUserSubscriptions(user.id);
await userSubscriptionService.getUserSubscriptions(user.id);
expect(noUserSubscriptions).toMatchObject([]);
});
test('Event log for subscription actions', async () => {
const user = await userStore.insert({
email: 'test@getunleash.io',
name: 'Sample Name',
});
await userSubscriptionService.unsubscribe(
user.id,
'productivity-report',
TEST_AUDIT_USER,
);
const unsubscribeEvent = (await eventsStore.getAll())[0];
expect(unsubscribeEvent).toEqual(
expect.objectContaining({
type: 'user-preference-updated',
data: {
subscription: 'productivity-report',
action: 'unsubscribed',
},
}),
);
await userSubscriptionService.subscribe(
user.id,
'productivity-report',
TEST_AUDIT_USER,
);
const subscribeEvent = (await eventsStore.getAll())[0];
expect(subscribeEvent).toEqual(
expect.objectContaining({
type: 'user-preference-updated',
data: {
subscription: 'productivity-report',
action: 'subscribed',
},
}),
);
});

View File

@ -1,4 +1,8 @@
import type { IUnleashConfig, IUnleashStores } from '../../types';
import {
UserPreferenceUpdatedEvent,
type IUnleashConfig,
type IUnleashStores,
} from '../../types';
import type { Logger } from '../../logger';
import type { IAuditUser } from '../../types/user';
import type {
@ -49,13 +53,13 @@ export class UserSubscriptionsService {
};
await this.userUnsubscribeStore.delete(entry);
// TODO: log an event
// await this.eventService.storeEvent(
// new UserSubscriptionEvent({
// data: { ...entry, action: 'subscribed' },
// auditUser,
// }),
// );
await this.eventService.storeEvent(
new UserPreferenceUpdatedEvent({
userId,
data: { subscription, action: 'subscribed' },
auditUser,
}),
);
}
async unsubscribe(
@ -69,12 +73,12 @@ export class UserSubscriptionsService {
};
await this.userUnsubscribeStore.insert(entry);
// TODO: log an event
// await this.eventService.storeEvent(
// new UserSubscriptionEvent({
// data: { ...entry, action: 'unsubscribed' },
// auditUser,
// }),
// );
await this.eventService.storeEvent(
new UserPreferenceUpdatedEvent({
userId,
data: { subscription, action: 'unsubscribed' },
auditUser,
}),
);
}
}

View File

@ -204,6 +204,8 @@ export const ACTIONS_CREATED = 'actions-created' as const;
export const ACTIONS_UPDATED = 'actions-updated' as const;
export const ACTIONS_DELETED = 'actions-deleted' as const;
export const USER_PREFERENCE_UPDATED = 'user-preference-updated' as const;
export const IEventTypes = [
APPLICATION_CREATED,
FEATURE_CREATED,
@ -351,6 +353,7 @@ export const IEventTypes = [
ACTIONS_CREATED,
ACTIONS_UPDATED,
ACTIONS_DELETED,
USER_PREFERENCE_UPDATED,
] as const;
export type IEventType = (typeof IEventTypes)[number];
@ -2024,3 +2027,18 @@ function mapUserToData(user: IUserEventData): any {
rootRole: user.rootRole,
};
}
export class UserPreferenceUpdatedEvent extends BaseEvent {
readonly userId;
readonly data: any;
constructor(eventData: {
userId: number;
data: any;
auditUser: IAuditUser;
}) {
super(USER_PREFERENCE_UPDATED, eventData.auditUser);
this.userId = eventData.userId;
this.data = eventData.data;
}
}

View File

@ -14,4 +14,4 @@ Production updates last month: {{productionUpdates}}
Go to your Insights to learn more: {{unleashUrl}}/insights
This email was sent to {{userEmail}}. Youve received this as you are a user of Unleash.
If you wish to unsubscribe, go to you profile settings <a href="{{unleashUrl}}/profile">here</a>.
If you wish to unsubscribe, go to you profile settings on {{unleashUrl}}/profile