nestjs-firebase-admin 0.4.5 → 0.5.8
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.
- package/LICENSE +1 -1
- package/README.md +22 -127
- package/art/logo.png +0 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/modules/admin/admin.module.js +36 -6
- package/dist/modules/admin/{admin.service.d.ts → services/admin.service.d.ts} +1 -1
- package/dist/modules/admin/{admin.service.js → services/admin.service.js} +1 -1
- package/dist/modules/admin/services/auth.service.d.ts +32 -0
- package/dist/modules/admin/services/auth.service.js +87 -0
- package/dist/modules/admin/{database.service.d.ts → services/database.service.d.ts} +1 -1
- package/dist/modules/admin/{database.service.js → services/database.service.js} +1 -1
- package/dist/modules/admin/services/firestore.service.d.ts +18 -0
- package/dist/modules/admin/services/firestore.service.js +94 -0
- package/dist/modules/admin/{messaging.service.js → services/messaging.service.js} +1 -1
- package/docs/_sidebar.md +10 -0
- package/docs/getting-started.md +82 -0
- package/docs/services/admin-service.md +99 -0
- package/docs/services/auth-service.md +123 -0
- package/docs/services/database-service.md +65 -0
- package/docs/services/firestore-service.md +69 -0
- package/docs/services/messaging-service.md +87 -0
- package/docs/testing.md +67 -0
- package/index.html +60 -0
- package/package.json +5 -5
- package/dist/modules/admin/admin.service.spec.d.ts +0 -1
- package/dist/modules/admin/admin.service.spec.js +0 -228
- package/dist/modules/admin/database.service.spec.d.ts +0 -1
- package/dist/modules/admin/database.service.spec.js +0 -235
- package/dist/modules/admin/messaging.service.spec.d.ts +0 -1
- package/dist/modules/admin/messaging.service.spec.js +0 -148
- /package/dist/modules/admin/{admin.constants.d.ts → constants/admin.constants.d.ts} +0 -0
- /package/dist/modules/admin/{admin.constants.js → constants/admin.constants.js} +0 -0
- /package/dist/modules/admin/{messaging.service.d.ts → services/messaging.service.d.ts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const testing_1 = require("@nestjs/testing");
|
|
13
|
-
const admin_service_1 = require("./admin.service");
|
|
14
|
-
const node_http_1 = require("node:http");
|
|
15
|
-
const rxjs_1 = require("rxjs");
|
|
16
|
-
const FIREBASE_ADMIN_INSTANCE_TOKEN = 'FIREBASE_ADMIN_INSTANCE_TOKEN';
|
|
17
|
-
jest.mock('firebase-admin/app', () => {
|
|
18
|
-
return {
|
|
19
|
-
getApp: jest.fn().mockReturnValue({ name: 'app-name', options: {} }),
|
|
20
|
-
getApps: jest.fn().mockReturnValue([{ name: 'app-name', options: {} }]),
|
|
21
|
-
deleteApp: jest.fn().mockResolvedValue(undefined),
|
|
22
|
-
applicationDefault: jest.fn().mockReturnValue('default-credential'),
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
jest.mock('firebase-admin', () => {
|
|
26
|
-
return {
|
|
27
|
-
initializeApp: jest.fn().mockReturnValue({ name: 'app-name', options: {} }),
|
|
28
|
-
credential: {
|
|
29
|
-
cert: jest.fn().mockReturnValue('mocked-credential'),
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
const firebaseAdmin = jest.requireMock('firebase-admin');
|
|
34
|
-
const firebaseAdminApp = jest.requireMock('firebase-admin/app');
|
|
35
|
-
describe('AdminService', () => {
|
|
36
|
-
let service;
|
|
37
|
-
const mockOptions = {
|
|
38
|
-
credential: {
|
|
39
|
-
projectId: 'mock-project',
|
|
40
|
-
clientEmail: 'mock@example.com',
|
|
41
|
-
privateKey: 'mock-key',
|
|
42
|
-
},
|
|
43
|
-
databaseURL: 'https://mock-project.firebaseio.com',
|
|
44
|
-
storageBucket: 'mock-project.appspot.com',
|
|
45
|
-
projectId: 'mock-project',
|
|
46
|
-
};
|
|
47
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
-
jest.clearAllMocks();
|
|
49
|
-
const mockApp = { name: 'app-name', options: {} };
|
|
50
|
-
firebaseAdmin.initializeApp.mockReturnValue(mockApp);
|
|
51
|
-
firebaseAdmin.credential.cert.mockReturnValue('mocked-credential');
|
|
52
|
-
const module = yield testing_1.Test.createTestingModule({
|
|
53
|
-
providers: [
|
|
54
|
-
admin_service_1.AdminService,
|
|
55
|
-
{
|
|
56
|
-
provide: FIREBASE_ADMIN_INSTANCE_TOKEN,
|
|
57
|
-
useValue: mockOptions,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
provide: 'FIREBASE_ADMIN_APP',
|
|
61
|
-
useValue: mockApp,
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
}).compile();
|
|
65
|
-
service = module.get(admin_service_1.AdminService);
|
|
66
|
-
}));
|
|
67
|
-
it('must be defined', () => {
|
|
68
|
-
expect(service).toBeDefined();
|
|
69
|
-
});
|
|
70
|
-
describe('constructor', () => {
|
|
71
|
-
it('must store the injected Firebase Admin app', () => {
|
|
72
|
-
expect(service.appRef).toEqual({ name: 'app-name', options: {} });
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('applicationDefault', () => {
|
|
76
|
-
it('should return default credentials with no arguments', () => {
|
|
77
|
-
const result = service.applicationDefault();
|
|
78
|
-
expect(firebaseAdminApp.applicationDefault).toHaveBeenCalledWith(undefined);
|
|
79
|
-
expect(result).toBe('default-credential');
|
|
80
|
-
});
|
|
81
|
-
it('must pass HTTP agent when provided', () => {
|
|
82
|
-
const httpAgent = new node_http_1.Agent();
|
|
83
|
-
const result = service.applicationDefault(httpAgent);
|
|
84
|
-
expect(firebaseAdminApp.applicationDefault).toHaveBeenCalledWith(httpAgent);
|
|
85
|
-
expect(result).toBe('default-credential');
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe('deleteApp', () => {
|
|
89
|
-
it('should call deleteApp function with the given app', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
-
const mockApp = { name: 'app-to-delete' };
|
|
91
|
-
yield service.deleteApp(mockApp);
|
|
92
|
-
expect(firebaseAdminApp.deleteApp).toHaveBeenCalledWith(mockApp);
|
|
93
|
-
}));
|
|
94
|
-
it('should return a resolved promise', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
-
const mockApp = { name: 'app-to-delete' };
|
|
96
|
-
yield expect(service.deleteApp(mockApp)).resolves.toBeUndefined();
|
|
97
|
-
}));
|
|
98
|
-
it('should propagate errors from deleteApp', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
|
-
firebaseAdminApp.deleteApp.mockRejectedValueOnce(new Error('Delete error'));
|
|
100
|
-
const mockApp = { name: 'app-with-error' };
|
|
101
|
-
yield expect(service.deleteApp(mockApp)).rejects.toThrow('Delete error');
|
|
102
|
-
}));
|
|
103
|
-
});
|
|
104
|
-
describe('getApps', () => {
|
|
105
|
-
it('should return all initialized apps', () => {
|
|
106
|
-
const mockApps = [{ name: 'app1' }, { name: 'app2' }];
|
|
107
|
-
firebaseAdminApp.getApps.mockReturnValueOnce(mockApps);
|
|
108
|
-
const result = service.getApps;
|
|
109
|
-
expect(firebaseAdminApp.getApps).toHaveBeenCalled();
|
|
110
|
-
expect(result).toEqual(mockApps);
|
|
111
|
-
});
|
|
112
|
-
it('should return an empty array when there are no apps', () => {
|
|
113
|
-
firebaseAdminApp.getApps.mockReturnValueOnce([]);
|
|
114
|
-
const result = service.getApps;
|
|
115
|
-
expect(result).toEqual([]);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
describe('getApp', () => {
|
|
119
|
-
it('should return the default app', () => {
|
|
120
|
-
const mockApp = { name: 'default-app' };
|
|
121
|
-
firebaseAdminApp.getApp.mockReturnValueOnce(mockApp);
|
|
122
|
-
const result = service.getApp;
|
|
123
|
-
expect(firebaseAdminApp.getApp).toHaveBeenCalled();
|
|
124
|
-
expect(result).toEqual(mockApp);
|
|
125
|
-
});
|
|
126
|
-
it('must propagate getApp errors', () => {
|
|
127
|
-
firebaseAdminApp.getApp.mockImplementationOnce(() => {
|
|
128
|
-
throw new Error('App not found');
|
|
129
|
-
});
|
|
130
|
-
expect(() => service.getApp).toThrow('App not found');
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
describe('admin', () => {
|
|
134
|
-
it('should return Firebase Admin SDK instance', () => {
|
|
135
|
-
const adminModule = service.admin();
|
|
136
|
-
expect(adminModule).toBeDefined();
|
|
137
|
-
expect(adminModule.initializeApp).toBe(firebaseAdmin.initializeApp);
|
|
138
|
-
expect(adminModule.credential.cert).toBe(firebaseAdmin.credential.cert);
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
describe('initializeAppObservable', () => {
|
|
142
|
-
it('must return an Observable with the app instance', () => {
|
|
143
|
-
return new Promise(done => {
|
|
144
|
-
const observable = service.initializeAppObservable();
|
|
145
|
-
expect(observable).toBeInstanceOf(rxjs_1.Observable);
|
|
146
|
-
observable.subscribe({
|
|
147
|
-
next: (app) => {
|
|
148
|
-
expect(app).toBeDefined();
|
|
149
|
-
expect(app).toEqual({ name: 'app-name', options: {} });
|
|
150
|
-
},
|
|
151
|
-
complete: () => {
|
|
152
|
-
done();
|
|
153
|
-
},
|
|
154
|
-
error: (_err) => {
|
|
155
|
-
done();
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
it('must complete the Observable after issuing the app', () => {
|
|
161
|
-
return new Promise(done => {
|
|
162
|
-
const completeSpy = jest.fn();
|
|
163
|
-
service.initializeAppObservable().subscribe({
|
|
164
|
-
next: () => { },
|
|
165
|
-
complete: () => {
|
|
166
|
-
completeSpy();
|
|
167
|
-
expect(completeSpy).toHaveBeenCalledTimes(1);
|
|
168
|
-
done();
|
|
169
|
-
},
|
|
170
|
-
error: (_err) => {
|
|
171
|
-
done();
|
|
172
|
-
},
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
it('must return a valid cleanup function when unsubscribing', () => {
|
|
177
|
-
const observable = service.initializeAppObservable();
|
|
178
|
-
const subscription = observable.subscribe(() => { });
|
|
179
|
-
expect(() => subscription.unsubscribe()).not.toThrow();
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
describe('appRef', () => {
|
|
183
|
-
it('should return the injected app instance', () => {
|
|
184
|
-
const result = service.appRef;
|
|
185
|
-
expect(result).toEqual({ name: 'app-name', options: {} });
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
describe('initializeApp', () => {
|
|
189
|
-
it('should return the injected app instance', () => {
|
|
190
|
-
const result = service.initializeApp();
|
|
191
|
-
expect(result).toEqual({ name: 'app-name', options: {} });
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
describe('complex use cases', () => {
|
|
195
|
-
it('should allow you to get an app and then delete it', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
196
|
-
const mockApp = { name: 'app-to-manage' };
|
|
197
|
-
firebaseAdminApp.getApp.mockReturnValueOnce(mockApp);
|
|
198
|
-
const app = service.getApp;
|
|
199
|
-
yield service.deleteApp(app);
|
|
200
|
-
expect(firebaseAdminApp.getApp).toHaveBeenCalled();
|
|
201
|
-
expect(firebaseAdminApp.deleteApp).toHaveBeenCalledWith(mockApp);
|
|
202
|
-
}));
|
|
203
|
-
it('should return the same app when appRef is called multiple times in a row', () => {
|
|
204
|
-
const firstCall = service.appRef;
|
|
205
|
-
const secondCall = service.appRef;
|
|
206
|
-
expect(firstCall).toBe(secondCall);
|
|
207
|
-
expect(firstCall).toEqual({ name: 'app-name', options: {} });
|
|
208
|
-
});
|
|
209
|
-
it('should be defined', () => {
|
|
210
|
-
expect(service).toBeDefined();
|
|
211
|
-
});
|
|
212
|
-
it('should return an array of apps', () => {
|
|
213
|
-
expect(service.getApps).toBeInstanceOf(Array);
|
|
214
|
-
});
|
|
215
|
-
it('should return an app', () => {
|
|
216
|
-
expect(service.getApp).toBeInstanceOf(Object);
|
|
217
|
-
});
|
|
218
|
-
it('should return an app reference', () => {
|
|
219
|
-
expect(service.appRef).toBeInstanceOf(Object);
|
|
220
|
-
});
|
|
221
|
-
it('should return an observable of an app', () => {
|
|
222
|
-
expect(service.initializeAppObservable()).toBeInstanceOf(Object);
|
|
223
|
-
});
|
|
224
|
-
it('should return a credential', () => {
|
|
225
|
-
expect(service.applicationDefault()).toBe('default-credential');
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const testing_1 = require("@nestjs/testing");
|
|
13
|
-
const database_service_1 = require("./database.service");
|
|
14
|
-
const DatabaseService_mock_1 = require("../../tests/mocks/DatabaseService.mock");
|
|
15
|
-
describe('DatabaseService', () => {
|
|
16
|
-
let service;
|
|
17
|
-
let mockService;
|
|
18
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
-
const module = yield testing_1.Test.createTestingModule({
|
|
20
|
-
providers: [
|
|
21
|
-
{
|
|
22
|
-
provide: database_service_1.DatabaseService,
|
|
23
|
-
useClass: DatabaseService_mock_1.DatabaseServiceMock,
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
}).compile();
|
|
27
|
-
service = module.get(database_service_1.DatabaseService);
|
|
28
|
-
mockService = service;
|
|
29
|
-
}));
|
|
30
|
-
afterEach(() => {
|
|
31
|
-
if (mockService.resetMocks) {
|
|
32
|
-
mockService.resetMocks();
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
it('should be defined', () => {
|
|
36
|
-
expect(service).toBeDefined();
|
|
37
|
-
});
|
|
38
|
-
describe('ref', () => {
|
|
39
|
-
it('should return a database reference', () => {
|
|
40
|
-
const ref = service.ref('test-path');
|
|
41
|
-
expect(ref).toBeDefined();
|
|
42
|
-
expect(ref.get).toBeDefined();
|
|
43
|
-
expect(ref.set).toBeDefined();
|
|
44
|
-
expect(ref.update).toBeDefined();
|
|
45
|
-
expect(ref.remove).toBeDefined();
|
|
46
|
-
expect(ref.push).toBeDefined();
|
|
47
|
-
});
|
|
48
|
-
it('should handle different path formats', () => {
|
|
49
|
-
const ref1 = service.ref('users/123/profile');
|
|
50
|
-
expect(ref1).toBeDefined();
|
|
51
|
-
const ref2 = service.ref('');
|
|
52
|
-
expect(ref2).toBeDefined();
|
|
53
|
-
const ref3 = service.ref('users/user.name@example.com');
|
|
54
|
-
expect(ref3).toBeDefined();
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
describe('get', () => {
|
|
58
|
-
it('should get data from a path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
-
const data = yield service.get('test-path');
|
|
60
|
-
expect(data).toBe('mock-data');
|
|
61
|
-
}));
|
|
62
|
-
it('should handle non-existent paths', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
-
const data = yield service.get('non-existent-path');
|
|
64
|
-
expect(data).toBe('mock-data');
|
|
65
|
-
}));
|
|
66
|
-
it('should handle error during data retrieval', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
-
const mockRef = service.ref('error-path');
|
|
68
|
-
mockRef.get = jest.fn().mockRejectedValue(new Error('Database error'));
|
|
69
|
-
yield expect(service.get('error-path')).rejects.toThrow('Database error');
|
|
70
|
-
}));
|
|
71
|
-
it('should call get method with correct path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
-
const path = 'test/specific/path';
|
|
73
|
-
const spyRef = jest.spyOn(service, 'ref');
|
|
74
|
-
yield service.get(path);
|
|
75
|
-
expect(spyRef).toHaveBeenCalledWith(path);
|
|
76
|
-
}));
|
|
77
|
-
it('should handle null value response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
-
const mockRef = service.ref('null-path');
|
|
79
|
-
mockRef.get = jest.fn().mockResolvedValue({ val: () => null });
|
|
80
|
-
const result = yield service.get('null-path');
|
|
81
|
-
expect(result).toBeNull();
|
|
82
|
-
}));
|
|
83
|
-
});
|
|
84
|
-
describe('set', () => {
|
|
85
|
-
it('should set data at a path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
-
const testData = { name: 'test' };
|
|
87
|
-
yield expect(service.set('test-path', testData)).resolves.not.toThrow();
|
|
88
|
-
}));
|
|
89
|
-
it('should handle complex data structures', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
-
const testData = {
|
|
91
|
-
name: 'test',
|
|
92
|
-
nested: {
|
|
93
|
-
field: 'value',
|
|
94
|
-
array: [1, 2, 3],
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
yield expect(service.set('test-path', testData)).resolves.not.toThrow();
|
|
98
|
-
}));
|
|
99
|
-
it('should handle error during set operation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
100
|
-
const mockRef = service.ref('error-path');
|
|
101
|
-
mockRef.set = jest.fn().mockRejectedValue(new Error('Permission denied'));
|
|
102
|
-
yield expect(service.set('error-path', { test: 'data' })).rejects.toThrow('Permission denied');
|
|
103
|
-
}));
|
|
104
|
-
it('should call set method with correct parameters', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
|
-
const path = 'users/123';
|
|
106
|
-
const data = { name: 'John Doe', age: 30 };
|
|
107
|
-
const refSpy = jest.spyOn(service, 'ref');
|
|
108
|
-
const setSpy = jest.spyOn(service.ref(path), 'set');
|
|
109
|
-
yield service.set(path, data);
|
|
110
|
-
expect(refSpy).toHaveBeenCalledWith(path);
|
|
111
|
-
expect(setSpy).toHaveBeenCalledWith(data);
|
|
112
|
-
}));
|
|
113
|
-
it('should set primitive data types', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
-
yield expect(service.set('string-path', 'test-string')).resolves.not.toThrow();
|
|
115
|
-
yield expect(service.set('number-path', 42)).resolves.not.toThrow();
|
|
116
|
-
yield expect(service.set('bool-path', true)).resolves.not.toThrow();
|
|
117
|
-
yield expect(service.set('null-path', null)).resolves.not.toThrow();
|
|
118
|
-
}));
|
|
119
|
-
});
|
|
120
|
-
describe('update', () => {
|
|
121
|
-
it('should update data at a path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
122
|
-
const testData = { name: 'updated' };
|
|
123
|
-
yield expect(service.update('test-path', testData)).resolves.not.toThrow();
|
|
124
|
-
}));
|
|
125
|
-
it('should handle partial updates', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
-
const testData = { 'nested.field': 'new-value' };
|
|
127
|
-
yield expect(service.update('test-path', testData)).resolves.not.toThrow();
|
|
128
|
-
}));
|
|
129
|
-
it('should handle error during update operation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
130
|
-
const mockRef = service.ref('error-path');
|
|
131
|
-
mockRef.update = jest.fn().mockRejectedValue(new Error('Update failed'));
|
|
132
|
-
yield expect(service.update('error-path', { name: 'test' })).rejects.toThrow('Update failed');
|
|
133
|
-
}));
|
|
134
|
-
it('should call update method with correct parameters', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
-
const path = 'users/profile';
|
|
136
|
-
const data = { lastActive: Date.now(), status: 'online' };
|
|
137
|
-
const refSpy = jest.spyOn(service, 'ref');
|
|
138
|
-
const updateSpy = jest.spyOn(service.ref(path), 'update');
|
|
139
|
-
yield service.update(path, data);
|
|
140
|
-
expect(refSpy).toHaveBeenCalledWith(path);
|
|
141
|
-
expect(updateSpy).toHaveBeenCalledWith(data);
|
|
142
|
-
}));
|
|
143
|
-
it('should update with empty object', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
-
yield expect(service.update('test-path', {})).resolves.not.toThrow();
|
|
145
|
-
}));
|
|
146
|
-
});
|
|
147
|
-
describe('remove', () => {
|
|
148
|
-
it('should remove data at a path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
|
-
yield expect(service.remove('test-path')).resolves.not.toThrow();
|
|
150
|
-
}));
|
|
151
|
-
it('should handle non-existent paths', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
-
yield expect(service.remove('non-existent-path')).resolves.not.toThrow();
|
|
153
|
-
}));
|
|
154
|
-
it('should handle error during remove operation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
155
|
-
const mockRef = service.ref('error-path');
|
|
156
|
-
mockRef.remove = jest.fn().mockRejectedValue(new Error('Delete failed'));
|
|
157
|
-
yield expect(service.remove('error-path')).rejects.toThrow('Delete failed');
|
|
158
|
-
}));
|
|
159
|
-
it('should call remove method with correct path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
-
const path = 'users/123/sessions';
|
|
161
|
-
const refSpy = jest.spyOn(service, 'ref');
|
|
162
|
-
const removeSpy = jest.spyOn(service.ref(path), 'remove');
|
|
163
|
-
yield service.remove(path);
|
|
164
|
-
expect(refSpy).toHaveBeenCalledWith(path);
|
|
165
|
-
expect(removeSpy).toHaveBeenCalled();
|
|
166
|
-
}));
|
|
167
|
-
});
|
|
168
|
-
describe('push', () => {
|
|
169
|
-
it('should push data to a path and return a key', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
170
|
-
const testData = { name: 'new-item' };
|
|
171
|
-
const key = yield service.push('test-path', testData);
|
|
172
|
-
expect(key).toBe('mock-key');
|
|
173
|
-
}));
|
|
174
|
-
it('should handle empty key case', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
175
|
-
const mockRef = service.ref('test-path');
|
|
176
|
-
mockRef.push = jest.fn().mockResolvedValue({ key: null });
|
|
177
|
-
const testData = { name: 'new-item' };
|
|
178
|
-
const key = yield service.push('test-path', testData);
|
|
179
|
-
expect(key).toBe('');
|
|
180
|
-
}));
|
|
181
|
-
it('should handle error during push operation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
-
const mockRef = service.ref('error-path');
|
|
183
|
-
mockRef.push = jest.fn().mockRejectedValue(new Error('Push failed'));
|
|
184
|
-
yield expect(service.push('error-path', { name: 'test' })).rejects.toThrow('Push failed');
|
|
185
|
-
}));
|
|
186
|
-
it('should call push method with correct parameters', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
|
-
const path = 'messages';
|
|
188
|
-
const data = { text: 'Hello world', timestamp: Date.now() };
|
|
189
|
-
const refSpy = jest.spyOn(service, 'ref');
|
|
190
|
-
const pushSpy = jest.spyOn(service.ref(path), 'push');
|
|
191
|
-
yield service.push(path, data);
|
|
192
|
-
expect(refSpy).toHaveBeenCalledWith(path);
|
|
193
|
-
expect(pushSpy).toHaveBeenCalledWith(data);
|
|
194
|
-
}));
|
|
195
|
-
it('should push different data types', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
196
|
-
yield expect(service.push('list/objects', { id: 1 })).resolves.toBe('mock-key');
|
|
197
|
-
yield expect(service.push('list/arrays', [1, 2, 3])).resolves.toBe('mock-key');
|
|
198
|
-
yield expect(service.push('list/strings', 'test string')).resolves.toBe('mock-key');
|
|
199
|
-
yield expect(service.push('list/numbers', 42)).resolves.toBe('mock-key');
|
|
200
|
-
}));
|
|
201
|
-
});
|
|
202
|
-
describe('combined operations', () => {
|
|
203
|
-
it('should perform get and update operations sequentially', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
204
|
-
const path = 'users/profile';
|
|
205
|
-
const getSpy = jest.spyOn(service, 'get');
|
|
206
|
-
const updateSpy = jest.spyOn(service, 'update');
|
|
207
|
-
const data = yield service.get(path);
|
|
208
|
-
yield service.update(path, { lastAccess: Date.now() });
|
|
209
|
-
expect(getSpy).toHaveBeenCalledWith(path);
|
|
210
|
-
expect(updateSpy).toHaveBeenCalled();
|
|
211
|
-
}));
|
|
212
|
-
it('should perform push and then get the pushed data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
213
|
-
const basePath = 'posts';
|
|
214
|
-
const postData = { title: 'Test Post', content: 'Content' };
|
|
215
|
-
const key = yield service.push(basePath, postData);
|
|
216
|
-
expect(key).toBe('mock-key');
|
|
217
|
-
const path = `${basePath}/${key}`;
|
|
218
|
-
const getSpy = jest.spyOn(service, 'get');
|
|
219
|
-
yield service.get(path);
|
|
220
|
-
expect(getSpy).toHaveBeenCalledWith(path);
|
|
221
|
-
}));
|
|
222
|
-
it('should handle transaction-like operations', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
223
|
-
const itemPath = 'items/123';
|
|
224
|
-
const itemData = { name: 'Updated Item', updated: true };
|
|
225
|
-
const refPath = 'users/456/items/123';
|
|
226
|
-
const refData = { updated: true, timestamp: Date.now() };
|
|
227
|
-
const setSpy = jest.spyOn(service, 'set');
|
|
228
|
-
const updateSpy = jest.spyOn(service, 'update');
|
|
229
|
-
yield service.set(itemPath, itemData);
|
|
230
|
-
yield service.update(refPath, refData);
|
|
231
|
-
expect(setSpy).toHaveBeenCalledWith(itemPath, itemData);
|
|
232
|
-
expect(updateSpy).toHaveBeenCalledWith(refPath, refData);
|
|
233
|
-
}));
|
|
234
|
-
});
|
|
235
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const testing_1 = require("@nestjs/testing");
|
|
13
|
-
const messaging_service_1 = require("./messaging.service");
|
|
14
|
-
const admin_constants_1 = require("./admin.constants");
|
|
15
|
-
jest.mock('firebase-admin/messaging', () => {
|
|
16
|
-
return {
|
|
17
|
-
Messaging: jest.fn().mockImplementation(() => ({
|
|
18
|
-
send: jest.fn().mockResolvedValue('message-id'),
|
|
19
|
-
sendMulticast: jest.fn().mockResolvedValue({
|
|
20
|
-
successCount: 1,
|
|
21
|
-
failureCount: 0,
|
|
22
|
-
responses: [{ messageId: 'message-id' }],
|
|
23
|
-
}),
|
|
24
|
-
subscribeToTopic: jest.fn().mockResolvedValue({
|
|
25
|
-
successCount: 1,
|
|
26
|
-
failureCount: 0,
|
|
27
|
-
errors: [],
|
|
28
|
-
}),
|
|
29
|
-
unsubscribeFromTopic: jest.fn().mockResolvedValue({
|
|
30
|
-
successCount: 1,
|
|
31
|
-
failureCount: 0,
|
|
32
|
-
errors: [],
|
|
33
|
-
}),
|
|
34
|
-
})),
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
describe('MessagingService', () => {
|
|
38
|
-
let service;
|
|
39
|
-
let mockMessaging;
|
|
40
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
-
const mockApp = {
|
|
42
|
-
messaging: jest.fn().mockReturnValue({
|
|
43
|
-
send: jest.fn().mockResolvedValue('message-id'),
|
|
44
|
-
sendMulticast: jest.fn().mockResolvedValue({
|
|
45
|
-
successCount: 1,
|
|
46
|
-
failureCount: 0,
|
|
47
|
-
responses: [{ messageId: 'message-id' }],
|
|
48
|
-
}),
|
|
49
|
-
subscribeToTopic: jest.fn().mockResolvedValue({
|
|
50
|
-
successCount: 1,
|
|
51
|
-
failureCount: 0,
|
|
52
|
-
errors: [],
|
|
53
|
-
}),
|
|
54
|
-
unsubscribeFromTopic: jest.fn().mockResolvedValue({
|
|
55
|
-
successCount: 1,
|
|
56
|
-
failureCount: 0,
|
|
57
|
-
errors: [],
|
|
58
|
-
}),
|
|
59
|
-
}),
|
|
60
|
-
};
|
|
61
|
-
const module = yield testing_1.Test.createTestingModule({
|
|
62
|
-
providers: [
|
|
63
|
-
messaging_service_1.MessagingService,
|
|
64
|
-
{
|
|
65
|
-
provide: admin_constants_1.FIREBASE_ADMIN_APP,
|
|
66
|
-
useValue: mockApp,
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
}).compile();
|
|
70
|
-
service = module.get(messaging_service_1.MessagingService);
|
|
71
|
-
mockMessaging = mockApp.messaging();
|
|
72
|
-
}));
|
|
73
|
-
it('should be defined', () => {
|
|
74
|
-
expect(service).toBeDefined();
|
|
75
|
-
});
|
|
76
|
-
describe('sendToDevice', () => {
|
|
77
|
-
it('should send a message to a single device', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
-
const token = 'device-token';
|
|
79
|
-
const payload = {
|
|
80
|
-
notification: {
|
|
81
|
-
title: 'Test Title',
|
|
82
|
-
body: 'Test Body',
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
const result = yield service.sendToDevice(token, payload);
|
|
86
|
-
expect(result).toBe('message-id');
|
|
87
|
-
expect(mockMessaging.send).toHaveBeenCalledWith(Object.assign({ token }, payload));
|
|
88
|
-
}));
|
|
89
|
-
});
|
|
90
|
-
describe('sendToDevices', () => {
|
|
91
|
-
it('should send a message to multiple devices', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
-
const tokens = ['token1', 'token2'];
|
|
93
|
-
const payload = {
|
|
94
|
-
notification: {
|
|
95
|
-
title: 'Test Title',
|
|
96
|
-
body: 'Test Body',
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
const result = yield service.sendToDevices(tokens, payload);
|
|
100
|
-
expect(result).toEqual({
|
|
101
|
-
successCount: 1,
|
|
102
|
-
failureCount: 0,
|
|
103
|
-
responses: [{ messageId: 'message-id' }],
|
|
104
|
-
});
|
|
105
|
-
expect(mockMessaging.sendMulticast).toHaveBeenCalledWith(Object.assign({ tokens }, payload));
|
|
106
|
-
}));
|
|
107
|
-
});
|
|
108
|
-
describe('sendToTopic', () => {
|
|
109
|
-
it('should send a message to a topic', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
-
const topic = 'test-topic';
|
|
111
|
-
const payload = {
|
|
112
|
-
notification: {
|
|
113
|
-
title: 'Test Title',
|
|
114
|
-
body: 'Test Body',
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
const result = yield service.sendToTopic(topic, payload);
|
|
118
|
-
expect(result).toBe('message-id');
|
|
119
|
-
expect(mockMessaging.send).toHaveBeenCalledWith(Object.assign({ topic }, payload));
|
|
120
|
-
}));
|
|
121
|
-
});
|
|
122
|
-
describe('subscribeToTopic', () => {
|
|
123
|
-
it('should subscribe devices to a topic', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
|
-
const tokens = ['token1', 'token2'];
|
|
125
|
-
const topic = 'test-topic';
|
|
126
|
-
const result = yield service.subscribeToTopic(tokens, topic);
|
|
127
|
-
expect(result).toEqual({
|
|
128
|
-
successCount: 1,
|
|
129
|
-
failureCount: 0,
|
|
130
|
-
errors: [],
|
|
131
|
-
});
|
|
132
|
-
expect(mockMessaging.subscribeToTopic).toHaveBeenCalledWith(tokens, topic);
|
|
133
|
-
}));
|
|
134
|
-
});
|
|
135
|
-
describe('unsubscribeFromTopic', () => {
|
|
136
|
-
it('should unsubscribe devices from a topic', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
137
|
-
const tokens = ['token1', 'token2'];
|
|
138
|
-
const topic = 'test-topic';
|
|
139
|
-
const result = yield service.unsubscribeFromTopic(tokens, topic);
|
|
140
|
-
expect(result).toEqual({
|
|
141
|
-
successCount: 1,
|
|
142
|
-
failureCount: 0,
|
|
143
|
-
errors: [],
|
|
144
|
-
});
|
|
145
|
-
expect(mockMessaging.unsubscribeFromTopic).toHaveBeenCalledWith(tokens, topic);
|
|
146
|
-
}));
|
|
147
|
-
});
|
|
148
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|