Skip to content

Commit 6b82966

Browse files
fixes
1 parent f3dc309 commit 6b82966

File tree

4 files changed

+278
-311
lines changed

4 files changed

+278
-311
lines changed

backend/__tests__/controllers/organizationController.test.ts

Lines changed: 127 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ jest.mock('crypto', () => ({
4141

4242
import {
4343
getAllOrganizations,
44+
registerOrganization,
4445
getOrganizationById,
45-
getCurrentOrganizationProfile,
46-
updateOrganizationProfile,
4746
updateOrganization,
4847
deleteOrganization,
4948
} from '../../controllers/organizationController';
@@ -79,11 +78,7 @@ const mockOrganization = {
7978
contactTitle: 'Executive Director',
8079
role: 'MEMBER' as OrganizationRole,
8180
status: 'ACTIVE' as OrganizationStatus,
82-
isActive: true,
8381
tags: ['Nashville', 'Senior Services', 'Healthcare'],
84-
emailVerified: true,
85-
inviteToken: null,
86-
inviteTokenExp: null,
8782
};
8883

8984
const mockAdminOrg = {
@@ -120,24 +115,8 @@ describe('OrganizationController', () => {
120115
await getAllOrganizations(req, res);
121116

122117
expect(prismaMock.organization.findMany).toHaveBeenCalledWith({
118+
where: {},
123119
orderBy: { name: 'asc' },
124-
select: {
125-
id: true,
126-
name: true,
127-
email: true,
128-
description: true,
129-
website: true,
130-
address: true,
131-
city: true,
132-
state: true,
133-
zipCode: true,
134-
phoneNumber: true,
135-
contactPerson: true,
136-
contactTitle: true,
137-
role: true,
138-
status: true,
139-
tags: true,
140-
},
141120
});
142121

143122
expect(res.json).toHaveBeenCalledWith(mockOrgs);
@@ -156,6 +135,116 @@ describe('OrganizationController', () => {
156135
});
157136
});
158137

138+
describe('registerOrganization', () => {
139+
it('should register new organization - POST /api/organizations/register', async () => {
140+
const req = createMockRequest({
141+
body: {
142+
email: 'neworg@nonprofit.org',
143+
password: 'securePassword123',
144+
name: 'New Community Services',
145+
contactPerson: 'John Smith',
146+
contactTitle: 'Executive Director',
147+
city: 'Memphis',
148+
state: 'TN',
149+
tags: ['Community', 'Services'],
150+
},
151+
});
152+
const res = createMockResponse();
153+
154+
prismaMock.organization.findFirst.mockResolvedValue(null);
155+
prismaMock.organization.create.mockResolvedValue({
156+
...mockOrganization,
157+
email: 'neworg@nonprofit.org',
158+
name: 'New Community Services',
159+
contactPerson: 'John Smith',
160+
status: 'PENDING',
161+
});
162+
163+
await registerOrganization(req, res);
164+
165+
expect(prismaMock.organization.findFirst).toHaveBeenCalledWith({
166+
where: {
167+
OR: [
168+
{ email: 'neworg@nonprofit.org' },
169+
{ name: 'New Community Services' }
170+
],
171+
},
172+
});
173+
174+
expect(admin.auth().createUser).toHaveBeenCalledWith({
175+
email: 'neworg@nonprofit.org',
176+
password: 'securePassword123',
177+
emailVerified: false,
178+
displayName: 'New Community Services',
179+
});
180+
181+
expect(prismaMock.organization.create).toHaveBeenCalledWith({
182+
data: {
183+
email: 'neworg@nonprofit.org',
184+
name: 'New Community Services',
185+
contactPerson: 'John Smith',
186+
contactTitle: 'Executive Director',
187+
description: undefined,
188+
website: undefined,
189+
address: undefined,
190+
city: 'Memphis',
191+
state: 'TN',
192+
zipCode: undefined,
193+
phoneNumber: undefined,
194+
tags: ['Community', 'Services'],
195+
firebaseUid: 'firebase-uid-123',
196+
role: 'MEMBER',
197+
status: 'PENDING',
198+
},
199+
});
200+
201+
expect(res.status).toHaveBeenCalledWith(201);
202+
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({
203+
email: 'neworg@nonprofit.org',
204+
name: 'New Community Services',
205+
status: 'PENDING',
206+
}));
207+
});
208+
209+
it('should reject registration with missing required fields - POST /api/organizations/register', async () => {
210+
const req = createMockRequest({
211+
body: {
212+
email: 'incomplete@nonprofit.org',
213+
// Missing password, name, contactPerson
214+
},
215+
});
216+
const res = createMockResponse();
217+
218+
await registerOrganization(req, res);
219+
220+
expect(res.status).toHaveBeenCalledWith(400);
221+
expect(res.json).toHaveBeenCalledWith({
222+
error: 'Email, password, name, and contact person are required'
223+
});
224+
});
225+
226+
it('should prevent duplicate registration - POST /api/organizations/register', async () => {
227+
const req = createMockRequest({
228+
body: {
229+
email: 'existing@nonprofit.org',
230+
password: 'password123',
231+
name: 'Existing Organization',
232+
contactPerson: 'Jane Doe',
233+
},
234+
});
235+
const res = createMockResponse();
236+
237+
prismaMock.organization.findFirst.mockResolvedValue(mockOrganization);
238+
239+
await registerOrganization(req, res);
240+
241+
expect(res.status).toHaveBeenCalledWith(400);
242+
expect(res.json).toHaveBeenCalledWith({
243+
error: 'Organization with this email or name already exists'
244+
});
245+
});
246+
});
247+
159248
describe('getOrganizationById', () => {
160249
it('should return organization by ID - GET /api/organizations/:id', async () => {
161250
const req = createMockRequest({
@@ -170,11 +259,6 @@ describe('OrganizationController', () => {
170259

171260
expect(prismaMock.organization.findUnique).toHaveBeenCalledWith({
172261
where: { id: 'org123' },
173-
select: expect.objectContaining({
174-
id: true,
175-
name: true,
176-
email: true,
177-
}),
178262
});
179263

180264
expect(res.json).toHaveBeenCalledWith(mockOrganization);
@@ -223,44 +307,41 @@ describe('OrganizationController', () => {
223307
});
224308
});
225309

226-
describe('getCurrentOrganizationProfile', () => {
310+
describe('getOrganizationById (/profile route)', () => {
227311
it('should return current org profile - GET /api/organizations/profile', async () => {
228312
const req = createMockRequest({
229313
user: { id: 'org123' },
314+
params: { id: 'profile' },
230315
});
231316
const res = createMockResponse();
232317

233318
prismaMock.organization.findUnique.mockResolvedValue(mockOrganization);
234319

235-
await getCurrentOrganizationProfile(req, res);
320+
await getOrganizationById(req, res);
236321

237322
expect(prismaMock.organization.findUnique).toHaveBeenCalledWith({
238323
where: { id: 'org123' },
239-
select: expect.objectContaining({
240-
id: true,
241-
name: true,
242-
email: true,
243-
}),
244324
});
245325

246326
expect(res.json).toHaveBeenCalledWith(mockOrganization);
247327
});
248328

249329
it('should return 401 for unauthenticated - GET /api/organizations/profile', async () => {
250-
const req = createMockRequest();
330+
const req = createMockRequest({ params: { id: 'profile' } });
251331
const res = createMockResponse();
252332

253-
await getCurrentOrganizationProfile(req, res);
333+
await getOrganizationById(req, res);
254334

255335
expect(res.status).toHaveBeenCalledWith(401);
256336
expect(res.json).toHaveBeenCalledWith({ error: 'Organization not authenticated' });
257337
});
258338
});
259339

260-
describe('updateOrganizationProfile', () => {
340+
describe('updateOrganization (/profile route)', () => {
261341
it('should update org profile - PUT /api/organizations/profile', async () => {
262342
const req = createMockRequest({
263343
user: { id: 'org123' },
344+
params: { id: 'profile' },
264345
body: {
265346
name: 'Updated Senior Services',
266347
description: 'Updated description',
@@ -277,7 +358,7 @@ describe('OrganizationController', () => {
277358
};
278359
prismaMock.organization.update.mockResolvedValue(updatedOrg);
279360

280-
await updateOrganizationProfile(req, res);
361+
await updateOrganization(req, res);
281362

282363
expect(prismaMock.organization.update).toHaveBeenCalledWith({
283364
where: { id: 'org123' },
@@ -287,11 +368,6 @@ describe('OrganizationController', () => {
287368
contactPerson: 'John Doe',
288369
contactTitle: 'New Director',
289370
}),
290-
select: expect.objectContaining({
291-
id: true,
292-
name: true,
293-
email: true,
294-
}),
295371
});
296372

297373
expect(res.json).toHaveBeenCalledWith(updatedOrg);
@@ -300,6 +376,7 @@ describe('OrganizationController', () => {
300376
it('should update org email and reset verification - PUT /api/organizations/profile', async () => {
301377
const req = createMockRequest({
302378
user: { id: 'org123' },
379+
params: { id: 'profile' },
303380
body: {
304381
email: 'newemail@nonprofit.org',
305382
name: 'Updated Senior Services',
@@ -316,11 +393,10 @@ describe('OrganizationController', () => {
316393
const updatedOrg = {
317394
...mockOrganization,
318395
email: 'newemail@nonprofit.org',
319-
emailVerified: false,
320396
};
321397
prismaMock.organization.update.mockResolvedValue(updatedOrg);
322398

323-
await updateOrganizationProfile(req, res);
399+
await updateOrganization(req, res);
324400

325401
expect(prismaMock.organization.findFirst).toHaveBeenCalledWith({
326402
where: {
@@ -337,9 +413,7 @@ describe('OrganizationController', () => {
337413
where: { id: 'org123' },
338414
data: expect.objectContaining({
339415
email: 'newemail@nonprofit.org',
340-
emailVerified: false,
341-
}),
342-
select: expect.any(Object),
416+
}),
343417
});
344418

345419
expect(res.json).toHaveBeenCalled();
@@ -348,6 +422,7 @@ describe('OrganizationController', () => {
348422
it('should reject duplicate email - PUT /api/organizations/profile', async () => {
349423
const req = createMockRequest({
350424
user: { id: 'org123' },
425+
params: { id: 'profile' },
351426
body: {
352427
email: 'existing@nonprofit.org',
353428
},
@@ -359,7 +434,7 @@ describe('OrganizationController', () => {
359434
email: 'existing@nonprofit.org',
360435
} as any);
361436

362-
await updateOrganizationProfile(req, res);
437+
await updateOrganization(req, res);
363438

364439
expect(res.status).toHaveBeenCalledWith(400);
365440
expect(res.json).toHaveBeenCalledWith({
@@ -373,6 +448,7 @@ describe('OrganizationController', () => {
373448
it('should handle Firebase email update failure - PUT /api/organizations/profile', async () => {
374449
const req = createMockRequest({
375450
user: { id: 'org123' },
451+
params: { id: 'profile' },
376452
body: {
377453
email: 'newemail@nonprofit.org',
378454
},
@@ -387,7 +463,7 @@ describe('OrganizationController', () => {
387463
const mockUpdateUser = admin.auth().updateUser as jest.Mock;
388464
mockUpdateUser.mockRejectedValue(new Error('Firebase error'));
389465

390-
await updateOrganizationProfile(req, res);
466+
await updateOrganization(req, res);
391467

392468
expect(res.status).toHaveBeenCalledWith(400);
393469
expect(res.json).toHaveBeenCalledWith({

0 commit comments

Comments
 (0)