strapi-plugin-notifier 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,122 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import makePreferenceService from '../../server/src/services/preference';
3
+ import { makePreferenceStrapi } from '../helpers';
4
+
5
+ describe('preference.isOptedOut (pure logic)', () => {
6
+ const { isOptedOut } = makePreferenceService({ strapi: {} as any });
7
+
8
+ it('returns true when globalOptOut is set', () => {
9
+ expect(isOptedOut({ userId: 1, globalOptOut: true, mutedTypes: [] }, 'info')).toBe(true);
10
+ });
11
+
12
+ it('returns true when type is in mutedTypes', () => {
13
+ expect(isOptedOut({ userId: 1, globalOptOut: false, mutedTypes: ['info'] }, 'info')).toBe(true);
14
+ });
15
+
16
+ it('returns false when type is not muted and globalOptOut is false', () => {
17
+ expect(isOptedOut({ userId: 1, globalOptOut: false, mutedTypes: ['warning'] }, 'info')).toBe(false);
18
+ });
19
+
20
+ it('returns false with empty mutedTypes and globalOptOut false', () => {
21
+ expect(isOptedOut({ userId: 1, globalOptOut: false, mutedTypes: [] }, 'error')).toBe(false);
22
+ });
23
+
24
+ it('globalOptOut overrides even when mutedTypes is empty', () => {
25
+ expect(isOptedOut({ userId: 1, globalOptOut: true, mutedTypes: [] }, 'success')).toBe(true);
26
+ });
27
+
28
+ it('mutes multiple types independently', () => {
29
+ const pref = { userId: 1, globalOptOut: false, mutedTypes: ['info', 'warning'] as any };
30
+ expect(isOptedOut(pref, 'info')).toBe(true);
31
+ expect(isOptedOut(pref, 'warning')).toBe(true);
32
+ expect(isOptedOut(pref, 'success')).toBe(false);
33
+ expect(isOptedOut(pref, 'error')).toBe(false);
34
+ });
35
+ });
36
+
37
+ describe('preference.get', () => {
38
+ it('returns default preference when no DB row exists', async () => {
39
+ const { strapi, _db } = makePreferenceStrapi({ findOne: vi.fn().mockResolvedValue(null) });
40
+ const svc = makePreferenceService({ strapi: strapi as any });
41
+
42
+ const pref = await svc.get(5);
43
+
44
+ expect(pref).toEqual({ userId: 5, globalOptOut: false, mutedTypes: [] });
45
+ expect(_db.findOne).toHaveBeenCalledWith({ where: { userId: 5 } });
46
+ });
47
+
48
+ it('returns stored preference when DB row exists', async () => {
49
+ const stored = { userId: 5, globalOptOut: true, mutedTypes: ['info', 'warning'] };
50
+ const { strapi } = makePreferenceStrapi({ findOne: vi.fn().mockResolvedValue(stored) });
51
+ const svc = makePreferenceService({ strapi: strapi as any });
52
+
53
+ const pref = await svc.get(5);
54
+
55
+ expect(pref.globalOptOut).toBe(true);
56
+ expect(pref.mutedTypes).toEqual(['info', 'warning']);
57
+ });
58
+
59
+ it('normalises null mutedTypes to empty array', async () => {
60
+ const stored = { userId: 5, globalOptOut: false, mutedTypes: null };
61
+ const { strapi } = makePreferenceStrapi({ findOne: vi.fn().mockResolvedValue(stored) });
62
+ const svc = makePreferenceService({ strapi: strapi as any });
63
+
64
+ const pref = await svc.get(5);
65
+ expect(pref.mutedTypes).toEqual([]);
66
+ });
67
+ });
68
+
69
+ describe('preference.upsert', () => {
70
+ it('creates a new row when none exists', async () => {
71
+ const { strapi, _db } = makePreferenceStrapi({
72
+ findOne: vi.fn().mockResolvedValue(null),
73
+ create: vi.fn().mockResolvedValue({
74
+ userId: 3,
75
+ globalOptOut: true,
76
+ mutedTypes: [],
77
+ }),
78
+ });
79
+ const svc = makePreferenceService({ strapi: strapi as any });
80
+
81
+ const pref = await svc.upsert(3, { globalOptOut: true });
82
+
83
+ expect(_db.create).toHaveBeenCalledWith({
84
+ data: expect.objectContaining({ userId: 3, globalOptOut: true }),
85
+ });
86
+ expect(_db.update).not.toHaveBeenCalled();
87
+ expect(pref.globalOptOut).toBe(true);
88
+ });
89
+
90
+ it('updates existing row when one exists', async () => {
91
+ const existing = { id: 10, userId: 3, globalOptOut: false, mutedTypes: [] };
92
+ const { strapi, _db } = makePreferenceStrapi({
93
+ findOne: vi.fn().mockResolvedValue(existing),
94
+ update: vi.fn().mockResolvedValue({ ...existing, mutedTypes: ['info'] }),
95
+ });
96
+ const svc = makePreferenceService({ strapi: strapi as any });
97
+
98
+ const pref = await svc.upsert(3, { mutedTypes: ['info'] as any });
99
+
100
+ expect(_db.update).toHaveBeenCalledWith({
101
+ where: { id: 10 },
102
+ data: { mutedTypes: ['info'] },
103
+ });
104
+ expect(_db.create).not.toHaveBeenCalled();
105
+ expect(pref.mutedTypes).toEqual(['info']);
106
+ });
107
+
108
+ it('persists globalOptOut=false to re-enable notifications', async () => {
109
+ const existing = { id: 7, userId: 2, globalOptOut: true, mutedTypes: [] };
110
+ const { strapi, _db } = makePreferenceStrapi({
111
+ findOne: vi.fn().mockResolvedValue(existing),
112
+ update: vi.fn().mockResolvedValue({ ...existing, globalOptOut: false }),
113
+ });
114
+ const svc = makePreferenceService({ strapi: strapi as any });
115
+
116
+ await svc.upsert(2, { globalOptOut: false });
117
+
118
+ expect(_db.update).toHaveBeenCalledWith(
119
+ expect.objectContaining({ data: { globalOptOut: false } })
120
+ );
121
+ });
122
+ });
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ include: ['tests/**/*.test.ts'],
8
+ },
9
+ });