Skip to content

Commit

Permalink
fix(release-notes): stop sending previously sent ones (#1845)
Browse files Browse the repository at this point in the history
  • Loading branch information
C0ZEN authored Nov 16, 2022
1 parent fc6c568 commit c2deaaf
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 8 deletions.
1 change: 1 addition & 0 deletions .idea/il-est-midi.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
"app-root-path": "3.1.0",
"axios": "1.1.3",
"chalk": "4.1.2",
"compare-versions": "5.0.1",
"discord.js": "13.12.0",
"dotenv": "15.0.1",
"express": "4.18.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
/**
* @description
* Add a new version each time the [Firebase guild]{@link IFirebaseGuild} model change
*
* Update the [current Firebase guild version]{@link FIREBASE_GUILD_CURRENT_VERSION} on change
*/
export enum FirebaseGuildVersionEnum {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ import _ from 'lodash';
/**
* @description
* Check if the given Firebase guild contains a [last release notes version]{@link IFirebaseGuildV2#lastReleaseNotesVersion}
*
* @see [sonia-link-001]{@link https://github.com/Sonia-corporation/sonia-discord/blob/master/CONTRIBUTING.md#sonia-link-001}
*
* @param {Readonly<IFirebaseGuild>} firebaseGuild The Firebase guild
*
* @returns {boolean} true when the given guild is at least [v2]{@link FirebaseGuildVersionEnum.V2}
*/
export function hasFirebaseGuildLastReleaseNotesVersion(
firebaseGuild: Readonly<IFirebaseGuild>
): firebaseGuild is IFirebaseGuildV2 | IFirebaseGuildV3 | IFirebaseGuildV4 {
): firebaseGuild is (IFirebaseGuildV2 | IFirebaseGuildV3 | IFirebaseGuildV4) & { lastReleaseNotesVersion: string } {
return _.includes(
[
FirebaseGuildVersionEnum.V2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export class FirebaseGuildsNewVersionCountService extends AbstractService {
* @description
* Each array is like a guild (without or without messages)
* Each {@link Message} is a message sent to Discord on a channel
*
* The goal here is to count the number of guilds
* Then the number of messages (ak channels)
* Then the number of messages per guild
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,48 @@ describe(`FirebaseGuildsNewVersionService`, (): void => {
firebaseGuildsServiceGetGuildsSpy.mockResolvedValue(querySnapshot);
});

describe(`when the Firebase guild last release notes version is smaller than the current version`, (): void => {
beforeEach((): void => {
appConfigServiceGetVersionSpy.mockReturnValue(`0.0.0`);
});

it(`should log that all Firebase guilds release notes were already sent`, async (): Promise<void> => {
expect.assertions(2);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(loggerServiceLogSpy).toHaveBeenCalledTimes(1);
expect(loggerServiceLogSpy).toHaveBeenCalledWith({
context: `FirebaseGuildsNewVersionService`,
message: `text-all Firebase guild hint-(1) release notes already sent`,
} as ILoggerLog);
});

it(`should not update the Firebase guild batch`, async (): Promise<void> => {
expect.assertions(1);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(updateMock).not.toHaveBeenCalled();
});

it(`should not commit the batch`, async (): Promise<void> => {
expect.assertions(1);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(commitMock).not.toHaveBeenCalled();
});

it(`should not send the release notes message for the guilds`, async (): Promise<void> => {
expect.assertions(1);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(sendNewReleaseNotesFromFirebaseGuildSpy).not.toHaveBeenCalled();
});
});

describe(`when the Firebase guild last release notes version is the same as the current version`, (): void => {
beforeEach((): void => {
appConfigServiceGetVersionSpy.mockReturnValue(`1.0.0`);
Expand Down Expand Up @@ -663,7 +705,197 @@ describe(`FirebaseGuildsNewVersionService`, (): void => {
});
});

describe(`when the Firebase guild last release notes version is not the same as the current version`, (): void => {
describe(`when the Firebase guild last release notes version is higher (patch) than the current version`, (): void => {
beforeEach((): void => {
appConfigServiceGetVersionSpy.mockReturnValue(`1.0.1`);
});

it(`should update the Firebase guild last release notes version in the batch`, async (): Promise<void> => {
expect.assertions(3);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(updateMock).toHaveBeenCalledTimes(1);
expect(updateMock).toHaveBeenCalledWith(queryDocumentSnapshot.ref, {
lastReleaseNotesVersion: `1.0.1`,
} as IUpdatedFirebaseGuildLastReleaseNotesVersion);
});

it(`should log that one Firebase guild is updating`, async (): Promise<void> => {
expect.assertions(3);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(loggerServiceLogSpy).toHaveBeenCalledTimes(1);
expect(loggerServiceLogSpy).toHaveBeenCalledWith({
context: `FirebaseGuildsNewVersionService`,
message: `text-updating value-1 Firebase guild...`,
} as ILoggerLog);
});

it(`should commit the batch`, async (): Promise<void> => {
expect.assertions(3);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(commitMock).toHaveBeenCalledTimes(1);
expect(commitMock).toHaveBeenCalledWith();
});

describe(`when the batch commit failed`, (): void => {
beforeEach((): void => {
commitMock.mockRejectedValue(new Error(`Commit error`));
});

it(`should not send the release notes message for the guild`, async (): Promise<void> => {
expect.assertions(2);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(sendNewReleaseNotesFromFirebaseGuildSpy).not.toHaveBeenCalled();
});
});

describe(`when the batch commit was successful`, (): void => {
beforeEach((): void => {
commitMock.mockResolvedValue(createMock<WriteResult[]>());
});

it(`should send the release notes message for the guild`, async (): Promise<void> => {
expect.assertions(2);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(sendNewReleaseNotesFromFirebaseGuildSpy).toHaveBeenCalledTimes(1);
expect(sendNewReleaseNotesFromFirebaseGuildSpy).toHaveBeenCalledWith(firebaseGuild);
});

describe(`when the release notes message sending failed for the guild`, (): void => {
beforeEach((): void => {
sendNewReleaseNotesFromFirebaseGuildSpy.mockRejectedValue(
new Error(`sendNewReleaseNotesFromFirebaseGuild error`)
);
});

it(`should log about the fail of the release notes message sending`, async (): Promise<void> => {
expect.assertions(2);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(loggerServiceErrorSpy).toHaveBeenCalledTimes(1);
expect(loggerServiceErrorSpy).toHaveBeenCalledWith({
context: `FirebaseGuildsNewVersionService`,
message: `text-release notes message sending failed for guild value-dummy-id`,
} as ILoggerLog);
});
});
});
});

describe(`when the Firebase guild last release notes version is higher (minor) than the current version`, (): void => {
beforeEach((): void => {
appConfigServiceGetVersionSpy.mockReturnValue(`1.1.0`);
});

it(`should update the Firebase guild last release notes version in the batch`, async (): Promise<void> => {
expect.assertions(3);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(updateMock).toHaveBeenCalledTimes(1);
expect(updateMock).toHaveBeenCalledWith(queryDocumentSnapshot.ref, {
lastReleaseNotesVersion: `1.1.0`,
} as IUpdatedFirebaseGuildLastReleaseNotesVersion);
});

it(`should log that one Firebase guild is updating`, async (): Promise<void> => {
expect.assertions(3);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(loggerServiceLogSpy).toHaveBeenCalledTimes(1);
expect(loggerServiceLogSpy).toHaveBeenCalledWith({
context: `FirebaseGuildsNewVersionService`,
message: `text-updating value-1 Firebase guild...`,
} as ILoggerLog);
});

it(`should commit the batch`, async (): Promise<void> => {
expect.assertions(3);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(commitMock).toHaveBeenCalledTimes(1);
expect(commitMock).toHaveBeenCalledWith();
});

describe(`when the batch commit failed`, (): void => {
beforeEach((): void => {
commitMock.mockRejectedValue(new Error(`Commit error`));
});

it(`should not send the release notes message for the guild`, async (): Promise<void> => {
expect.assertions(2);

await expect(firstValueFrom(service.sendNewReleaseNotesToEachGuild$())).rejects.toThrow(
new Error(`Commit error`)
);

expect(sendNewReleaseNotesFromFirebaseGuildSpy).not.toHaveBeenCalled();
});
});

describe(`when the batch commit was successful`, (): void => {
beforeEach((): void => {
commitMock.mockResolvedValue(createMock<WriteResult[]>());
});

it(`should send the release notes message for the guild`, async (): Promise<void> => {
expect.assertions(2);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(sendNewReleaseNotesFromFirebaseGuildSpy).toHaveBeenCalledTimes(1);
expect(sendNewReleaseNotesFromFirebaseGuildSpy).toHaveBeenCalledWith(firebaseGuild);
});

describe(`when the release notes message sending failed for the guild`, (): void => {
beforeEach((): void => {
sendNewReleaseNotesFromFirebaseGuildSpy.mockRejectedValue(
new Error(`sendNewReleaseNotesFromFirebaseGuild error`)
);
});

it(`should log about the fail of the release notes message sending`, async (): Promise<void> => {
expect.assertions(2);

await firstValueFrom(service.sendNewReleaseNotesToEachGuild$());

expect(loggerServiceErrorSpy).toHaveBeenCalledTimes(1);
expect(loggerServiceErrorSpy).toHaveBeenCalledWith({
context: `FirebaseGuildsNewVersionService`,
message: `text-release notes message sending failed for guild value-dummy-id`,
} as ILoggerLog);
});
});
});
});

describe(`when the Firebase guild last release notes version is higher (major) than the current version`, (): void => {
beforeEach((): void => {
appConfigServiceGetVersionSpy.mockReturnValue(`2.0.0`);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { isUpToDateFirebaseGuild } from '../../functions/guilds/is-up-to-date-fi
import { IFirebaseGuildChannel } from '../../types/guilds/channels/firebase-guild-channel';
import { IFirebaseGuild } from '../../types/guilds/firebase-guild';
import { IFirebaseGuildVFinal } from '../../types/guilds/firebase-guild-v-final';
import { compareVersions } from 'compare-versions';
import { Guild, GuildChannel, Message, ThreadChannel } from 'discord.js';
import { QueryDocumentSnapshot, QuerySnapshot, WriteBatch } from 'firebase-admin/firestore';
import _ from 'lodash';
Expand All @@ -37,6 +38,18 @@ import { mergeMap, take, tap } from 'rxjs/operators';

const NO_GUILD = 0;
const ONE_GUILD = 1;
const LOWER_VERSION = -1;

// eslint-disable-next-line @typescript-eslint/no-magic-numbers
type IGreaterVersion = 1;

// eslint-disable-next-line @typescript-eslint/no-magic-numbers
type ILowerVersion = -1;

// eslint-disable-next-line @typescript-eslint/no-magic-numbers
type ISameVersion = 0;

type IComparisonVersion = ISameVersion | IGreaterVersion | ILowerVersion;

export class FirebaseGuildsNewVersionService extends AbstractService {
private static _instance: FirebaseGuildsNewVersionService;
Expand Down Expand Up @@ -376,7 +389,11 @@ export class FirebaseGuildsNewVersionService extends AbstractService {
const appVersion: string = AppConfigService.getInstance().getVersion();

if (hasFirebaseGuildLastReleaseNotesVersion(firebaseGuild)) {
return !_.isEqual(firebaseGuild.lastReleaseNotesVersion, appVersion);
const comparison: IComparisonVersion = compareVersions(firebaseGuild.lastReleaseNotesVersion, appVersion);

if (comparison === LOWER_VERSION) {
return true;
}
}

return false;
Expand Down

0 comments on commit c2deaaf

Please sign in to comment.