mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
feat: add user preference change to event log (#8652)
This commit is contained in:
parent
7c192378d6
commit
7aa74cccd3
@ -1,7 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
|
type IEventStore,
|
||||||
type IUnleashConfig,
|
type IUnleashConfig,
|
||||||
type IUnleashStores,
|
type IUnleashStores,
|
||||||
type IUser,
|
type IUserStore,
|
||||||
TEST_AUDIT_USER,
|
TEST_AUDIT_USER,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import type { UserSubscriptionsService } from './user-subscriptions-service';
|
import type { UserSubscriptionsService } from './user-subscriptions-service';
|
||||||
@ -13,25 +14,27 @@ import type { IUserSubscriptionsReadModel } from './user-subscriptions-read-mode
|
|||||||
|
|
||||||
let stores: IUnleashStores;
|
let stores: IUnleashStores;
|
||||||
let db: ITestDb;
|
let db: ITestDb;
|
||||||
|
let userStore: IUserStore;
|
||||||
let userSubscriptionService: UserSubscriptionsService;
|
let userSubscriptionService: UserSubscriptionsService;
|
||||||
let userSubscriptionsReadModel: IUserSubscriptionsReadModel;
|
let userSubscriptionsReadModel: IUserSubscriptionsReadModel;
|
||||||
|
let eventsStore: IEventStore;
|
||||||
let config: IUnleashConfig;
|
let config: IUnleashConfig;
|
||||||
let user: IUser;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
db = await dbInit('user_subscriptions', getLogger);
|
db = await dbInit('user_subscriptions', getLogger);
|
||||||
stores = db.stores;
|
stores = db.stores;
|
||||||
config = createTestConfig({});
|
config = createTestConfig({});
|
||||||
|
|
||||||
|
userStore = stores.userStore;
|
||||||
userSubscriptionService = createUserSubscriptionsService(config)(
|
userSubscriptionService = createUserSubscriptionsService(config)(
|
||||||
db.rawDatabase,
|
db.rawDatabase,
|
||||||
);
|
);
|
||||||
userSubscriptionsReadModel = db.stores.userSubscriptionsReadModel;
|
userSubscriptionsReadModel = db.stores.userSubscriptionsReadModel;
|
||||||
|
eventsStore = db.stores.eventStore;
|
||||||
|
});
|
||||||
|
|
||||||
user = await stores.userStore.insert({
|
beforeEach(async () => {
|
||||||
email: 'test@getunleash.io',
|
await userStore.deleteAll();
|
||||||
name: 'Sample Name',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@ -39,6 +42,11 @@ afterAll(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Subscribe and unsubscribe', async () => {
|
test('Subscribe and unsubscribe', async () => {
|
||||||
|
const user = await userStore.insert({
|
||||||
|
email: 'test@getunleash.io',
|
||||||
|
name: 'Sample Name',
|
||||||
|
});
|
||||||
|
|
||||||
const subscribers = await userSubscriptionsReadModel.getSubscribedUsers(
|
const subscribers = await userSubscriptionsReadModel.getSubscribedUsers(
|
||||||
'productivity-report',
|
'productivity-report',
|
||||||
);
|
);
|
||||||
@ -47,7 +55,7 @@ test('Subscribe and unsubscribe', async () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const userSubscriptions =
|
const userSubscriptions =
|
||||||
await userSubscriptionsReadModel.getUserSubscriptions(user.id);
|
await userSubscriptionService.getUserSubscriptions(user.id);
|
||||||
expect(userSubscriptions).toMatchObject(['productivity-report']);
|
expect(userSubscriptions).toMatchObject(['productivity-report']);
|
||||||
|
|
||||||
await userSubscriptionService.unsubscribe(
|
await userSubscriptionService.unsubscribe(
|
||||||
@ -62,6 +70,49 @@ test('Subscribe and unsubscribe', async () => {
|
|||||||
expect(noSubscribers).toMatchObject([]);
|
expect(noSubscribers).toMatchObject([]);
|
||||||
|
|
||||||
const noUserSubscriptions =
|
const noUserSubscriptions =
|
||||||
await userSubscriptionsReadModel.getUserSubscriptions(user.id);
|
await userSubscriptionService.getUserSubscriptions(user.id);
|
||||||
expect(noUserSubscriptions).toMatchObject([]);
|
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',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@ -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 { Logger } from '../../logger';
|
||||||
import type { IAuditUser } from '../../types/user';
|
import type { IAuditUser } from '../../types/user';
|
||||||
import type {
|
import type {
|
||||||
@ -49,13 +53,13 @@ export class UserSubscriptionsService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await this.userUnsubscribeStore.delete(entry);
|
await this.userUnsubscribeStore.delete(entry);
|
||||||
// TODO: log an event
|
await this.eventService.storeEvent(
|
||||||
// await this.eventService.storeEvent(
|
new UserPreferenceUpdatedEvent({
|
||||||
// new UserSubscriptionEvent({
|
userId,
|
||||||
// data: { ...entry, action: 'subscribed' },
|
data: { subscription, action: 'subscribed' },
|
||||||
// auditUser,
|
auditUser,
|
||||||
// }),
|
}),
|
||||||
// );
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async unsubscribe(
|
async unsubscribe(
|
||||||
@ -69,12 +73,12 @@ export class UserSubscriptionsService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await this.userUnsubscribeStore.insert(entry);
|
await this.userUnsubscribeStore.insert(entry);
|
||||||
// TODO: log an event
|
await this.eventService.storeEvent(
|
||||||
// await this.eventService.storeEvent(
|
new UserPreferenceUpdatedEvent({
|
||||||
// new UserSubscriptionEvent({
|
userId,
|
||||||
// data: { ...entry, action: 'unsubscribed' },
|
data: { subscription, action: 'unsubscribed' },
|
||||||
// auditUser,
|
auditUser,
|
||||||
// }),
|
}),
|
||||||
// );
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,8 @@ export const ACTIONS_CREATED = 'actions-created' as const;
|
|||||||
export const ACTIONS_UPDATED = 'actions-updated' as const;
|
export const ACTIONS_UPDATED = 'actions-updated' as const;
|
||||||
export const ACTIONS_DELETED = 'actions-deleted' as const;
|
export const ACTIONS_DELETED = 'actions-deleted' as const;
|
||||||
|
|
||||||
|
export const USER_PREFERENCE_UPDATED = 'user-preference-updated' as const;
|
||||||
|
|
||||||
export const IEventTypes = [
|
export const IEventTypes = [
|
||||||
APPLICATION_CREATED,
|
APPLICATION_CREATED,
|
||||||
FEATURE_CREATED,
|
FEATURE_CREATED,
|
||||||
@ -351,6 +353,7 @@ export const IEventTypes = [
|
|||||||
ACTIONS_CREATED,
|
ACTIONS_CREATED,
|
||||||
ACTIONS_UPDATED,
|
ACTIONS_UPDATED,
|
||||||
ACTIONS_DELETED,
|
ACTIONS_DELETED,
|
||||||
|
USER_PREFERENCE_UPDATED,
|
||||||
] as const;
|
] as const;
|
||||||
export type IEventType = (typeof IEventTypes)[number];
|
export type IEventType = (typeof IEventTypes)[number];
|
||||||
|
|
||||||
@ -2024,3 +2027,18 @@ function mapUserToData(user: IUserEventData): any {
|
|||||||
rootRole: user.rootRole,
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,4 +14,4 @@ Production updates last month: {{productionUpdates}}
|
|||||||
Go to your Insights to learn more: {{unleashUrl}}/insights
|
Go to your Insights to learn more: {{unleashUrl}}/insights
|
||||||
|
|
||||||
This email was sent to {{userEmail}}. You’ve received this as you are a user of Unleash.
|
This email was sent to {{userEmail}}. You’ve 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
|
||||||
|
Loading…
Reference in New Issue
Block a user