diff --git a/tests/admin.test.ts b/tests/admin.test.ts index 6c53f572..0ea9fda3 100644 --- a/tests/admin.test.ts +++ b/tests/admin.test.ts @@ -1,6 +1,6 @@ import { ActivityScope, ActivityType, SubmitAttendanceForUsersRequest, UserAccessType } from '../types'; import { ControllerFactory } from './controllers'; -import { DatabaseConnection, EventFactory, UserFactory, PortalState } from './data'; +import { DatabaseConnection, EventFactory, PortalState, UserFactory } from './data'; beforeAll(async () => { await DatabaseConnection.connect(); @@ -20,11 +20,11 @@ describe('retroactive attendance submission', () => { const conn = await DatabaseConnection.get(); const users = UserFactory.create(3); const emails = users.map((user) => user.email); - const [proxyUser] = UserFactory.with({ accessType: UserAccessType.ADMIN }); + const [admin] = UserFactory.with({ accessType: UserAccessType.ADMIN }); const [event] = EventFactory.create(1); await new PortalState() - .createUsers([...users, proxyUser]) + .createUsers([...users, admin]) .createEvents([event]) .write(); @@ -32,11 +32,11 @@ describe('retroactive attendance submission', () => { const adminController = ControllerFactory.admin(conn); const attendanceController = ControllerFactory.attendance(conn); - await adminController.submitAttendanceForUsers({ users: emails, event: event.uuid }, proxyUser); + await adminController.submitAttendanceForUsers({ users: emails, event: event.uuid }, admin); for (let u = 0; u < users.length; u += 1) { const user = users[u]; - const userResponse = await userController.getUser({ uuid: user.uuid }, proxyUser); + const userResponse = await userController.getUser({ uuid: user.uuid }, admin); expect(userResponse.user.points).toEqual(user.points + event.pointValue); @@ -44,7 +44,7 @@ describe('retroactive attendance submission', () => { expect(attendanceResponse.attendances).toHaveLength(1); expect(attendanceResponse.attendances[0].event).toStrictEqual(event.getPublicEvent()); - const activityResponse = await userController.getUserActivityStream({ uuid: user.uuid }, proxyUser); + const activityResponse = await userController.getUserActivityStream({ uuid: user.uuid }, admin); expect(activityResponse.activity).toHaveLength(2); expect(activityResponse.activity[1].pointsEarned).toEqual(event.pointValue); @@ -56,11 +56,14 @@ describe('retroactive attendance submission', () => { test('does not log activity, attendance, and points for users who already attended', async () => { const conn = await DatabaseConnection.get(); const [user] = UserFactory.create(1); - const [proxyUser] = UserFactory.with({ accessType: UserAccessType.ADMIN }); + const [admin] = UserFactory.with({ accessType: UserAccessType.ADMIN }); const [event] = EventFactory.create(1); await new PortalState() - .createUsers([user, proxyUser]) + // Create users at beginning of time to ensure that account creation time does not + // end up after event attendance time, causing the order guarantee for activities + // below to fail. + .createUsers([user, admin]) .createEvents([event]) .attendEvents([user], [event]) .write(); @@ -71,28 +74,33 @@ describe('retroactive attendance submission', () => { await adminController.submitAttendanceForUsers( { users: [user.email], event: event.uuid }, - proxyUser, + admin, ); - const userResponse = await userController.getUser({ uuid: user.uuid }, proxyUser); - const attendanceResponse = await attendanceController.getAttendancesForCurrentUser(user); - const activityResponse = await userController.getCurrentUserActivityStream(user); - + const userResponse = await userController.getUser({ uuid: user.uuid }, admin); expect(userResponse.user.points).toEqual(user.points); + + const attendanceResponse = await attendanceController.getAttendancesForCurrentUser(user); expect(attendanceResponse.attendances).toHaveLength(1); + expect(attendanceResponse.attendances[0].event.uuid).toEqual(event.uuid); + expect(attendanceResponse.attendances[0].asStaff).toEqual(false); + + const activityResponse = await userController.getCurrentUserActivityStream(user); expect(activityResponse.activity).toHaveLength(2); expect(activityResponse.activity[1].description).toBeNull(); + expect(activityResponse.activity[1].type).toEqual(ActivityType.ATTEND_EVENT); + expect(activityResponse.activity[1].pointsEarned).toEqual(event.pointValue); }); test('logs proper activity and point rewards for staff attendance', async () => { const conn = await DatabaseConnection.get(); const [user] = UserFactory.create(1); const [staffUser] = UserFactory.with({ accessType: UserAccessType.STAFF }); - const [proxyUser] = UserFactory.with({ accessType: UserAccessType.ADMIN }); + const [admin] = UserFactory.with({ accessType: UserAccessType.ADMIN }); const [event] = EventFactory.with({ requiresStaff: true, staffPointBonus: 10 }); await new PortalState() - .createUsers([user, staffUser, proxyUser]) + .createUsers([user, staffUser, admin]) .createEvents([event]) .write(); @@ -104,16 +112,73 @@ describe('retroactive attendance submission', () => { asStaff: true, }; - await adminController.submitAttendanceForUsers(request, proxyUser); - - const userResponse = await userController.getUser({ uuid: user.uuid }, proxyUser); - const staffUserResponse = await userController.getUser({ uuid: staffUser.uuid }, proxyUser); - const activityResponse = await userController.getCurrentUserActivityStream(user); - const staffActivityResponse = await userController.getCurrentUserActivityStream(staffUser); + await adminController.submitAttendanceForUsers(request, admin); + const userResponse = await userController.getUser({ uuid: user.uuid }, admin); expect(userResponse.user.points).toEqual(event.pointValue); + + const staffUserResponse = await userController.getUser({ uuid: staffUser.uuid }, admin); expect(staffUserResponse.user.points).toEqual(event.pointValue + event.staffPointBonus); + + const activityResponse = await userController.getCurrentUserActivityStream(user); expect(activityResponse.activity[1].type).toEqual(ActivityType.ATTEND_EVENT); + + const staffActivityResponse = await userController.getCurrentUserActivityStream(staffUser); expect(staffActivityResponse.activity[1].type).toEqual(ActivityType.ATTEND_EVENT_AS_STAFF); }); }); + +describe('email retrieval', () => { + test('gets all the emails of stored users', async () => { + const conn = await DatabaseConnection.get(); + const users = UserFactory.create(5); + const emails = users.map((user) => user.email.toLowerCase()); + const [admin] = UserFactory.with({ accessType: UserAccessType.ADMIN }); + + await new PortalState() + .createUsers([...users, admin]) + .write(); + + const response = await ControllerFactory.admin(conn).getAllEmails(admin); + expect(expect.arrayContaining(response.emails)).toEqual([...emails, admin.email]); + }); +}); + +describe('bonus points submission', () => { + test('updates points and activity to the users in the bonus request', async () => { + const conn = await DatabaseConnection.get(); + const [userNotGettingBonus, ...users] = UserFactory.create(5); + const emails = users.map((user) => user.email.toLowerCase()); + const [admin] = UserFactory.with({ accessType: UserAccessType.ADMIN }); + + await new PortalState() + .createUsers([...users, userNotGettingBonus, admin]) + .write(); + + const bonus = { + description: 'Test addition of bonus points', + users: emails, + points: 200, + }; + + const createBonusResponse = await ControllerFactory.admin(conn).addBonus({ bonus }, admin); + expect(createBonusResponse.emails).toEqual(expect.arrayContaining(emails)); + + const userController = ControllerFactory.user(conn); + + for (let u = 0; u < users.length; u += 1) { + const user = users[u]; + const getUserResponse = await userController.getUser({ uuid: user.uuid }, admin); + expect(getUserResponse.user.points).toEqual(200); + + const activityResponse = await userController.getCurrentUserActivityStream(user); + expect(activityResponse.activity).toHaveLength(2); + expect(activityResponse.activity[1].description).toEqual(bonus.description); + expect(activityResponse.activity[1].type).toEqual(ActivityType.BONUS_POINTS); + expect(activityResponse.activity[1].pointsEarned).toEqual(bonus.points); + } + + const getNoBonusUserResponse = await userController.getUser({ uuid: userNotGettingBonus.uuid }, admin); + expect(getNoBonusUserResponse.user.points).toEqual(0); + }); +}); diff --git a/tests/data/PortalState.ts b/tests/data/PortalState.ts index 2ae7e93a..e4307d2d 100644 --- a/tests/data/PortalState.ts +++ b/tests/data/PortalState.ts @@ -1,5 +1,6 @@ import * as rfdc from 'rfdc'; import { flatten } from 'underscore'; +import * as moment from 'moment'; import { AttendanceModel } from '../../models/AttendanceModel'; import { EventModel } from '../../models/EventModel'; import { MerchandiseCollectionModel } from '../../models/MerchandiseCollectionModel'; @@ -61,6 +62,7 @@ export class PortalState { user, type: ActivityType.ACCOUNT_CREATE, scope: ActivityScope.PUBLIC, + timestamp: moment().subtract(1, 'months'), })); } return this; @@ -97,6 +99,7 @@ export class PortalState { type: asStaff ? ActivityType.ATTEND_EVENT_AS_STAFF : ActivityType.ATTEND_EVENT, timestamp, scope: ActivityScope.PUBLIC, + pointsEarned, })); } }