Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into andy/StoreItemPage
Browse files Browse the repository at this point in the history
  • Loading branch information
SheepTester committed Jan 21, 2024
2 parents e96356c + 2484444 commit 846638c
Show file tree
Hide file tree
Showing 118 changed files with 2,127 additions and 593 deletions.
7 changes: 6 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@
}
]
},
"ignorePatterns": "src/**/*.d.ts"
"ignorePatterns": [
"src/**/*.d.ts",
"**/public/sw.js",
"**/public/workbox-*.js",
"**/public/worker-*.js"
]
}
21 changes: 9 additions & 12 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

# Info

Closes **[ISSUE NUMBER]**. (If there is no issue for this pull request yet, please create one or
delete this line if the pull request is for a very minor tweak).
Closes **[ISSUE NUMBER]**.

# Description

What changes did you make? List all distinct problems that this PR addresses. Explain any relevant
motivation or context.
<!-- If there is no issue for this pull request yet, please create one or
delete this line if the pull request is for a very minor tweak. -->

[description]

<!-- What changes did you make? List all distinct problems that this PR addresses. Explain any relevant
motivation or context. -->

## Changes

- [Fill in here]
Expand All @@ -33,21 +33,18 @@ motivation or context.
I have tested that my changes fully resolve the linked issue ...

- [ ] locally on Desktop.
- [ ] locally on mobile - use https://ngrok.io to get a copy on a mobile device
- [ ] on the live deployment preview on Desktop.
- [ ] on the live deployment preview on Mobile.
- [ ] I have run and passed all new and existing Cypress tests. Add screenshots below.
- [ ] I have added new Cypress tests that are passing.

# Checklist

- [ ] I have performed a self-review of my own code.
- [ ] I have followed the style guidelines of this project.
- [ ] I have documented my code's `src/lib` functions and commented hard to understand areas
- [ ] I have documented any new functions in `/src/lib/*` and commented hard to understand areas
anywhere else.
- [ ] My changes produce no new warnings.

# Screenshots

Please include a screenshot of your Cypress testing suite passing successfully.

If you made any visual changes to the website, please include relevant screenshots below.
<!-- If you made any visual changes to the website, please include relevant screenshots below. -->
18 changes: 18 additions & 0 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: E2E Cypress tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
# Install npm dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v6
env:
NEXT_PUBLIC_ACM_API_URL: https://testing.api.acmucsd.com/api/v2
with:
start: yarn dev:start
wait-on: 'http://localhost:3000'
install-command: yarn install
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,11 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# PWA files
**/public/sw.js
**/public/workbox-*.js
**/public/worker-*.js
**/public/sw.js.map
**/public/workbox-*.js.map
**/public/worker-*.js.map
20 changes: 0 additions & 20 deletions cypress/e2e/pages/auth/login.cy.ts

This file was deleted.

35 changes: 35 additions & 0 deletions cypress/e2e/pages/edit-profile.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/// <reference types="cypress" />

describe('Edit Profile Page', () => {
beforeEach(() => {
cy.login('standard');
cy.location('pathname').should('equal', '/');
cy.visit('/profile/edit');
cy.location('pathname').should('equal', '/profile/edit');
});

it('Should update profile preview', () => {
// write something new to make sure it can save
cy.typeInForm('First', new Date().toISOString());
cy.get('button').contains('Save').click();

cy.fixture('profile').then(profile => {
const { first, last, bio, major, year } = profile;

cy.typeInForm('First', first);
cy.typeInForm('Last', last);
cy.selectInForm('Major', major);
cy.selectInForm('Graduation Year', year);
cy.typeInForm('Biography', bio);
cy.get('button').contains('Save').click();

cy.get('.Toastify').contains('Changes saved!').should('exist');

cy.get('section:contains("Current Profile")').within(() => {
Object.values(profile).forEach((value: string | number) => {
cy.contains(value).should('exist');
});
});
});
});
});
30 changes: 30 additions & 0 deletions cypress/e2e/pages/forgot-password.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/// <reference types="cypress" />

describe('Forgot Password Page', () => {
beforeEach(() => {
cy.visit('/forgot-password');
});

it('Should fail with missing email', () => {
cy.contains('button', 'Submit').click();
cy.contains('p', 'Required').should('exist');
});

it('Should fail with unknown email', () => {
const email = '[email protected]';
cy.get('input[name="email"]').type(email);
cy.contains('button', 'Submit').click();

cy.get('.Toastify').contains('There is no account associated with that email').should('exist');
});

it('Should succeed with valid email', () => {
cy.fixture('accounts').then(({ standard }) => {
const { email } = standard;
cy.get('input[name="email"]').type(email);
cy.contains('button', 'Submit').click();

cy.get('.Toastify').contains('Success').should('exist');
});
});
});
79 changes: 79 additions & 0 deletions cypress/e2e/pages/login.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/// <reference types="cypress" />

describe('Login Page', () => {
beforeEach(() => {
cy.visit('/login');
});

it('Should succeed with valid member login', () => {
cy.fixture('accounts').then(({ standard }) => {
const { email, password } = standard;

cy.get('input[name="email"]').type(email);
cy.get('input[name="password"]').type(password);
cy.get('button').contains('Sign In').click();

cy.location('pathname').should('equal', '/');
cy.getCookie('ACCESS_TOKEN').should('exist');
});
});

it('Should succeed with valid admin login', () => {
cy.fixture('accounts').then(({ admin }) => {
const { email, password } = admin;

cy.get('input[name="email"]').type(email);
cy.get('input[name="password"]').type(password);
cy.get('button').contains('Sign In').click();

cy.location('pathname').should('equal', '/');
cy.getCookie('ACCESS_TOKEN').should('exist');
cy.getCookie('USER').should('exist');
});
});

it('Should fail with invalid credentials', () => {
const [email, password] = ['[email protected]', 'abc'];

cy.get('input[name="email"]').type(email);
cy.get('input[name="password"]').type(password);
cy.get('button').contains('Sign In').click();

cy.get('.Toastify').contains('Unable to login').should('exist');
cy.location('pathname').should('equal', '/login');
});

it('Should fail with missing username', () => {
cy.fixture('accounts').then(({ standard }) => {
const { password } = standard;

cy.get('input[name="password"]').type(password);
cy.get('button').contains('Sign In').click();

cy.location('pathname').should('equal', '/login');
cy.contains('p', 'Required').should('exist');
});
});

it('Should fail with missing password', () => {
cy.fixture('accounts').then(({ standard }) => {
const { email } = standard;

cy.get('input[name="email"]').type(email);
cy.get('button').contains('Sign In').click();

cy.location('pathname').should('equal', '/login');
cy.contains('p', 'Required').should('exist');
});
});

it('Should link to forgot password page', () => {
cy.get('a').contains('Forgot your password?').click();
cy.location('pathname').should('equal', '/forgot-password');
});

it('Should link to account register page', () => {
cy.get('a').contains('Sign Up').click();
cy.location('pathname').should('equal', '/register');
});
});
7 changes: 7 additions & 0 deletions cypress/e2e/pages/register.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// <reference types="cypress" />

describe('Register Page', () => {
beforeEach(() => {
cy.visit('/register');
});
});
6 changes: 5 additions & 1 deletion cypress/fixtures/accounts.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"admin": {
"username": "[email protected]",
"email": "[email protected]",
"password": "password"
},
"standard": {
"email": "[email protected]",
"password": "password"
}
}
7 changes: 7 additions & 0 deletions cypress/fixtures/profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"first": "John",
"last": "Doe",
"bio": "I am a testing account.",
"major": "Computer Engineering",
"year": "2026"
}
49 changes: 49 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
declare global {
namespace Cypress {
interface Chainable {
/**
* Log in as the specified user, pulling details from accounts.json
* @example cy.login('standard')
*/
login(account: string): Chainable<void>;

/**
* Type text into a form input or textarea under specified label
* @param label - text of label that the input is a child of
* @param value - text to be typed into input
*/
typeInForm(label: string, value: string): Chainable<void>;

/**
* Select the given option in a select under specified label
* @param label - text of label that the select is a child of
* @param value - option to be selected
*/
selectInForm(label: string, value: string): Chainable<void>;
}
}
}

Cypress.Commands.add('login', (account: string) => {
cy.fixture('accounts.json').then(accs => {
if (!(account in accs))
throw new Error(`Account '${account}' isn't specified in \`accounts.json\``);
const { email, password } = accs[account];

cy.visit('/login');
cy.get('input[name="email"]').type(email);
cy.get('input[name="password"]').type(password);
cy.get('button').contains('Sign In').click();
});
});

Cypress.Commands.add('typeInForm', (label: string, value: string) => {
cy.get(`label:contains("${label}") input, label:contains("${label}") textarea`).as('input');
cy.get('@input').clear();
cy.get('@input').type(value as string);
});

Cypress.Commands.add('selectInForm', (label: string, value: string | number) => {
cy.get(`label:contains("${label}") select`).select(value);
});

export {};
9 changes: 8 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
const env = process.env.NODE_ENV;
const isDevelopment = env !== 'production';

const withPWA = require('next-pwa')({
dest: 'public',
register: true,
skipWaiting: true,
disable: isDevelopment,
});

/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
Expand Down Expand Up @@ -37,4 +44,4 @@ const nextConfig = {
},
};

module.exports = nextConfig;
module.exports = withPWA(nextConfig);
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"lint:fix": "yarn prettier && eslint --fix \"src/**/*.+(js|jsx|ts|tsx)\" && stylelint --fix \"**/*.scss\"",
"type-css": "yarn typed-scss-modules src/ --exportType default --logLevel silent --watch",
"dev": "yarn type-css & yarn lint && next dev",
"dev:start": "next dev",
"build": "next build",
"start": "next start",
"prod": "next build && next start",
Expand All @@ -34,10 +35,11 @@
"axios": "^1.6.0",
"axios-middleware": "^0.3.1",
"cookies-next": "^2.1.1",
"cypress": "^13.2.0",
"cypress": "13.6.2",
"ics": "^3.7.2",
"luxon": "^3.3.0",
"next": "^13.2.5-canary.30",
"next-pwa": "^5.6.0",
"next-themes": "^0.2.1",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand All @@ -51,11 +53,11 @@
"validator": "^13.9.0"
},
"devDependencies": {
"@types/totp-generator": "^0.0.5",
"@types/lodash": "^4.14.191",
"@types/luxon": "^3.3.0",
"@types/node": "18.8.1",
"@types/react": "18.0.21",
"@types/totp-generator": "^0.0.5",
"@types/validator": "^13.7.14",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"eslint": "8.24.0",
Expand Down
3 changes: 3 additions & 0 deletions public/assets/icons/edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 846638c

Please sign in to comment.