Skip to content

Commit

Permalink
Merge branch 'master' into feature/merch-store-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
maxwn04 committed Sep 28, 2024
2 parents fc395ab + cd976af commit 9fe76c9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
steps:
- checkout
- setup_remote_docker:
version: 20.10.2
version: docker24
# Caching done for docker images and stored for future workflows.
## https://circleci.com/docs/caching
- restore_cache:
Expand Down
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @sumeet-bansal @shravanhariharan2 @dowhep @nik-dange
* @shravanhariharan2 @dowhep @nik-dange
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@acmucsd/membership-portal",
"version": "3.6.1",
"version": "3.6.2",
"description": "REST API for ACM UCSD's membership portal.",
"main": "index.d.ts",
"files": [
Expand Down
1 change: 1 addition & 0 deletions services/MerchStoreService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ export default class MerchStoreService {
});
}

>>>>>>> master
public async getCartItems(options: string[]): Promise<MerchandiseItemOptionModel[]> {
return this.transactions.readOnly(async (txn) => {
const merchItemOptionRepository = Repositories.merchStoreItemOption(txn);
Expand Down
30 changes: 3 additions & 27 deletions services/UserAuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { InjectManager } from 'typeorm-typedi-extensions';
import { EntityManager } from 'typeorm';
import { ExpressCheckinModel } from 'models/ExpressCheckinModel';
import { UserRepository } from '../repositories/UserRepository';
import { Uuid, ActivityType, UserState, UserRegistration } from '../types';
import { Uuid, ActivityType, UserState, UserRegistration, UserAccessType } from '../types';
import { Config } from '../config';
import { UserModel } from '../models/UserModel';
import Repositories, { TransactionsManager } from '../repositories';
import UserAccountService from './UserAccountService';

interface AuthToken {
uuid: Uuid;
admin: boolean;
accessType: UserAccessType;
}

@Service()
Expand Down Expand Up @@ -111,30 +111,6 @@ export default class UserAuthService {
return user;
}

public async login(email: string, pass: string): Promise<string> {
const authenticatedUser = await this.transactions.readWrite(async (txn) => {
let user = await Repositories
.user(txn)
.findByEmail(email.toLowerCase());
if (!user) throw new NotFoundError('There is no account associated with that email');
if (user.isBlocked()) throw new ForbiddenError('Your account has been blocked');
if (!(await user.verifyPass(pass))) throw new ForbiddenError('Incorrect password');
await Repositories.activity(txn).logActivity({
user,
type: ActivityType.ACCOUNT_LOGIN,
});
if (user.state === UserState.PASSWORD_RESET) {
user = await Repositories.user(txn).upsertUser(user, { state: UserState.ACTIVE });
}
return user;
});
const token: AuthToken = {
uuid: authenticatedUser.uuid,
admin: authenticatedUser.isAdmin(),
};
return jwt.sign(token, Config.auth.secret, { expiresIn: Config.auth.tokenLifespan });
}

public async checkCredentials(email: string, pass: string): Promise<UserModel> {
const authenticatedUser = await this.transactions.readWrite(async (txn) => {
const user = await Repositories
Expand All @@ -156,7 +132,7 @@ export default class UserAuthService {
public static generateAuthToken(user: UserModel): string {
const token: AuthToken = {
uuid: user.uuid,
admin: user.isAdmin(),
accessType: user.accessType,
};
return jwt.sign(token, Config.auth.secret, { expiresIn: Config.auth.tokenLifespan });
}
Expand Down
56 changes: 56 additions & 0 deletions tests/merchOrder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,62 @@ describe('merch order pickup events', () => {
expect(persistedPickupEvent.pickupEvent.orderLimit).toEqual(2);
});

test('members cannot update their orders\' pickup events if the new pickup event is full', async () => {
const conn = await DatabaseConnection.get();
const member = UserFactory.fake({ credits: 10000 });
const item = MerchFactory.fakeItem({
hidden: false,
monthlyLimit: 100,
});
const option = MerchFactory.fakeOption({
item,
quantity: 2,
price: 2000,
});
const firstPickupEvent = MerchFactory.fakeFutureOrderPickupEvent({
orderLimit: 1,
});

const secondPickupEvent = MerchFactory.fakeFutureOrderPickupEvent({
orderLimit: 1,
});

await new PortalState()
.createUsers(member)
.createMerchItem(item)
.createMerchItemOptions(option)
.createOrderPickupEvents(firstPickupEvent, secondPickupEvent)
.orderMerch(member, [{ option, quantity: 1 }], firstPickupEvent)
.write();

const emailService = mock(EmailService);
when(emailService.sendOrderConfirmation(member.email, member.firstName, anything()))
.thenResolve();

// place order to secondPickupEvent
const order = [
{
option: option.uuid,
quantity: 1,
},
];
const placeMerchOrderRequest = {
order,
pickupEvent: secondPickupEvent.uuid,
};

const merchController = ControllerFactory.merchStore(conn, instance(emailService));
const placedOrderResponse = await merchController.placeMerchOrder(placeMerchOrderRequest, member);
const placedOrder = placedOrderResponse.order;

// attempt to reschedule to firstPickupEvent
const orderParams = { uuid: placedOrder.uuid };
const newPickupEventParams = { pickupEvent: firstPickupEvent.uuid };
await expect(merchController.rescheduleOrderPickup(orderParams, newPickupEventParams, member))
.rejects
.toThrow('This merch pickup event is full! Please choose a different pickup event');
});

test('placing an order with a pickup event that has reached the order limit fails', async () => {
const conn = await DatabaseConnection.get();
const member = UserFactory.fake({ points: 100 });
Expand Down

0 comments on commit 9fe76c9

Please sign in to comment.