Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(productivity-report): user subscripton read model #8654

Merged
merged 3 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init';
import getLogger from '../../../test/fixtures/no-logger';
import { UserSubscriptionsReadModel } from './user-subscriptions-read-model';
import type { IUserSubscriptionsReadModel } from './user-subscriptions-read-model-type';
import EventEmitter from 'events';
import { SUBSCRIPTION_TYPES } from './user-subscriptions-read-model-type';
import type { IUnleashStores, IUserStore } from '../../types';
import type { IUserUnsubscribeStore } from './user-unsubscribe-store-type';

let db: ITestDb;
let stores: IUnleashStores;
let userStore: IUserStore;
let userUnsubscribeStore: IUserUnsubscribeStore;
let userSubscriptionsReadModel: IUserSubscriptionsReadModel;

const subscription =
'productivity-report' satisfies (typeof SUBSCRIPTION_TYPES)[number];

beforeAll(async () => {
db = await dbInit('user_subscriptions_read_model_test', getLogger);
stores = db.stores;
userStore = stores.userStore;
userUnsubscribeStore = stores.userUnsubscribeStore;
const eventBus = new EventEmitter();
userSubscriptionsReadModel = new UserSubscriptionsReadModel(
db.rawDatabase,
eventBus,
);
});

beforeEach(async () => {
await db.stores.userStore.deleteAll();
});

afterAll(async () => {
await db.destroy();
});

describe('getSubscribedUsers', () => {
test('returns users that did not unsubscribe', async () => {
const user1 = await userStore.insert({
email: '[email protected]',
name: 'User One',
});
const user2 = await userStore.insert({
email: '[email protected]',
name: 'User Two',
});
const user3 = await userStore.insert({
email: '[email protected]',
name: 'User Three',
});

await userUnsubscribeStore.insert({
userId: user2.id,
subscription,
});

const subscribers =
await userSubscriptionsReadModel.getSubscribedUsers(subscription);

expect(subscribers).toHaveLength(2);
expect(subscribers).toEqual(
expect.arrayContaining([
{ email: '[email protected]', name: 'User One' },
{ email: '[email protected]', name: 'User Three' },
]),
);
});

test('reflects changes after unsubscribe and resubscribe', async () => {
const user = await userStore.insert({
email: '[email protected]',
name: 'User Seven',
});

let subscribers =
await userSubscriptionsReadModel.getSubscribedUsers(subscription);
expect(subscribers).toEqual(
expect.arrayContaining([
{ email: '[email protected]', name: 'User Seven' },
]),
);

await userUnsubscribeStore.insert({
userId: user.id,
subscription,
});
subscribers =
await userSubscriptionsReadModel.getSubscribedUsers(subscription);
expect(subscribers).not.toEqual(
expect.arrayContaining([
{ email: '[email protected]', name: 'User Seven' },
]),
);

await userUnsubscribeStore.delete({
userId: user.id,
subscription,
});

subscribers =
await userSubscriptionsReadModel.getSubscribedUsers(subscription);
expect(subscribers).toEqual(
expect.arrayContaining([
{ email: '[email protected]', name: 'User Seven' },
]),
);
});

test('should not include deleted users', async () => {
const user = await userStore.insert({
email: '[email protected]',
name: 'To Delete',
});

await userStore.delete(user.id);

const subscribers =
await userSubscriptionsReadModel.getSubscribedUsers(subscription);

expect(subscribers).toHaveLength(0);
});
});

describe('getUserSubscriptions', () => {
test(' returns all subscriptions if user has not unsubscribed', async () => {
Tymek marked this conversation as resolved.
Show resolved Hide resolved
Tymek marked this conversation as resolved.
Show resolved Hide resolved
const user = await userStore.insert({
email: '[email protected]',
name: 'User Four',
});

const userSubscriptions =
await userSubscriptionsReadModel.getUserSubscriptions(user.id);

expect(userSubscriptions).toEqual(SUBSCRIPTION_TYPES);
});

test('returns correct subscriptions if user unsubscribed and resubscribed', async () => {
const user = await userStore.insert({
email: '[email protected]',
name: 'User Five',
});
const subscription =
'productivity-report' satisfies (typeof SUBSCRIPTION_TYPES)[number];

await userUnsubscribeStore.insert({
userId: user.id,
subscription,
});

const userSubscriptions =
await userSubscriptionsReadModel.getUserSubscriptions(user.id);

expect(userSubscriptions).not.toContain(subscription);

await userUnsubscribeStore.delete({
userId: user.id,
subscription,
});

const userSubscriptionsAfterResubscribe =
await userSubscriptionsReadModel.getUserSubscriptions(user.id);

expect(userSubscriptionsAfterResubscribe).toContain(subscription);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class UserSubscriptionsReadModel implements IUserSubscriptionsReadModel {
.select(USER_COLUMNS)
.whereNotIn('id', unsubscribedUserIdsQuery)
.andWhere('is_service', false)
.andWhere('deleted_at', null)
.andWhereNot('email', null);

return users.map(mapRowToSubscriber);
Expand Down
Loading