Skip to content

Commit c80a150

Browse files
authored
Merge pull request #684 from UTDNebula/develop
Sync with main
2 parents e2aa260 + 5f83c12 commit c80a150

25 files changed

+680
-232
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ yarn-error.log*
4949
# See docs/ide-config.md for more information.
5050
.idea
5151
.vs/
52+
.editorconfig
5253

5354
prisma/generated
5455

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ public
66

77
node_modules/
88
prisma/generated
9+
10+
**/.mypy_cache/
11+
**/venv/

cypress/data/dummytranscript.pdf

8.24 KB
Binary file not shown.

cypress/e2e/create-plan.cy.ts

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,56 @@
11
describe('Plan creation flow', () => {
2-
before('Setup', () => {
2+
beforeEach('Setup', () => {
33
cy.resetDbAndLogin();
44
cy.visit('/app/home');
55
});
66

77
const planName = "Mr. Bob's Plan";
88

99
it('Create blank plan', () => {
10+
// Open add plan dropdown
11+
cy.task('log', 'Opening blank plan modal...');
12+
cy.dataTestId('add-new-plan-btn').click();
13+
cy.dataTestId('add-blank-plan-btn').click();
14+
15+
// Modal should be visible
16+
cy.dataTestId('create-blank-plan-page').then(($el) => Cypress.dom.isVisible($el));
17+
18+
// Fill out plan creation form
19+
cy.task('log', 'Filling out plan creation form...');
20+
cy.dataTestId('plan-name-input').type(planName);
21+
cy.dataTestId('major-autocomplete').type('Computer');
22+
cy.getDropdownOptions()
23+
.contains('Computer Science')
24+
.then(($el) => {
25+
cy.wrap($el.get(0).innerText).as('major');
26+
$el.click();
27+
});
28+
29+
// Create plan without upload transcript
30+
cy.task('log', 'Creating plan...');
31+
cy.dataTestId('create-plan-btn').click();
32+
33+
// Wait and verify redirect to plan
34+
cy.task('log', 'Verifying redirect...');
35+
cy.url({ timeout: 20000 }).should('include', '/app/plans/');
36+
37+
// Check plan information
38+
cy.task('log', 'Verifying plan information');
39+
cy.get('@major').then((majorAlias) => {
40+
// Check plan title
41+
cy.dataTestId('plan-title')
42+
.then(($el) => $el.text())
43+
.should('eq', planName);
44+
45+
// Check plan major
46+
const major = `${majorAlias}`; // Whack workaround
47+
cy.dataTestId('plan-major')
48+
.then(($el) => $el.text())
49+
.should('eq', major);
50+
});
51+
});
52+
53+
it('Create custom plan', () => {
1054
// Open add plan dropdown
1155
cy.task('log', 'Opening custom plan modal...');
1256
cy.dataTestId('add-new-plan-btn').click();
@@ -26,9 +70,56 @@ describe('Plan creation flow', () => {
2670
$el.click();
2771
});
2872

29-
// Create plan without upload transcript
73+
// Create plan with uploading transcript
3074
cy.task('log', 'Creating plan...');
3175
cy.dataTestId('next-btn').click();
76+
cy.dataTestId('upload-transcript-btn').click();
77+
78+
cy.get('input[type=file]').selectFile('cypress/data/dummytranscript.pdf', { force: true });
79+
cy.dataTestId('create-plan-btn').click();
80+
81+
// Wait and verify redirect to plan
82+
cy.task('log', 'Verifying redirect...');
83+
cy.url({ timeout: 20000 }).should('include', '/app/plans/');
84+
85+
// Check plan information
86+
cy.task('log', 'Verifying plan information');
87+
cy.get('@major').then((majorAlias) => {
88+
// Check plan title
89+
cy.dataTestId('plan-title')
90+
.then(($el) => $el.text())
91+
.should('eq', planName);
92+
93+
// Check plan major
94+
const major = `${majorAlias}`; // Whack workaround
95+
cy.dataTestId('plan-major')
96+
.then(($el) => $el.text())
97+
.should('eq', major);
98+
});
99+
});
100+
101+
it('Create template plan', () => {
102+
// Open add plan dropdown
103+
cy.task('log', 'Opening template plan modal...');
104+
cy.dataTestId('add-new-plan-btn').click();
105+
cy.dataTestId('add-template-plan-btn').click();
106+
107+
// Modal should be visible
108+
cy.dataTestId('create-template-plan-page').then(($el) => Cypress.dom.isVisible($el));
109+
110+
// Fill out plan creation form
111+
cy.task('log', 'Filling out plan creation form...');
112+
cy.dataTestId('plan-name-input').type(planName);
113+
cy.dataTestId('major-autocomplete').type('Computer');
114+
cy.getDropdownOptions()
115+
.contains('Computer Science')
116+
.then(($el) => {
117+
cy.wrap($el.get(0).innerText).as('major');
118+
$el.click();
119+
});
120+
121+
// Create template plan without upload transcript
122+
cy.task('log', 'Creating plan...');
32123
cy.dataTestId('create-plan-btn').click();
33124

34125
// Wait and verify redirect to plan

next.config.js

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,64 @@
11
/* eslint-disable @typescript-eslint/no-var-requires */
22
const { withSentryConfig } = require('@sentry/nextjs');
3+
const fetch = require('node-fetch');
34

45
/* eslint-disable @typescript-eslint/no-var-requires */
56

6-
const withBundleAnalyzer = require('@next/bundle-analyzer')({
7-
enabled: process.env.ANALYZE === 'true',
8-
});
7+
const checkValidatorAvailability = async () => {
8+
try {
9+
const response = await fetch(`${process.env.NEXT_PUBLIC_VALIDATOR}/health`);
10+
if (response.ok) {
11+
return true;
12+
} else {
13+
return false;
14+
}
15+
} catch (error) {
16+
return false;
17+
}
18+
};
919

10-
const nextConfig = withBundleAnalyzer({
11-
modularizeImports: {
12-
'@mui/material': {
13-
transform: '@mui/material/{{member}}',
20+
module.exports = async (phase) => {
21+
if (phase === 'phase-development-server') {
22+
const isValidatorReachable = await checkValidatorAvailability();
23+
24+
if (!isValidatorReachable) {
25+
console.error('Start validator server first before running next dev server.');
26+
process.exit(1);
27+
}
28+
}
29+
30+
const withBundleAnalyzer = require('@next/bundle-analyzer')({
31+
enabled: process.env.ANALYZE === 'true',
32+
});
33+
34+
const nextConfig = withBundleAnalyzer({
35+
modularizeImports: {
36+
'@mui/material': {
37+
transform: '@mui/material/{{member}}',
38+
},
39+
'@mui/icons-material': {
40+
transform: '@mui/icons-material/{{member}}',
41+
},
1442
},
15-
'@mui/icons-material': {
16-
transform: '@mui/icons-material/{{member}}',
43+
compiler: {
44+
removeConsole: process.env.NODE_ENV === 'production',
1745
},
18-
},
19-
compiler: {
20-
removeConsole: process.env.NODE_ENV === 'production',
21-
},
22-
rewrites: async () => {
23-
return [
24-
{
25-
source: '/',
26-
destination: '/index.html',
27-
},
28-
];
29-
},
30-
});
46+
rewrites: async () => {
47+
return [
48+
{
49+
source: '/',
50+
destination: '/index.html',
51+
},
52+
];
53+
},
54+
});
3155

32-
module.exports = withSentryConfig(
33-
nextConfig,
34-
{ silent: true },
35-
// tunnelRoute set to bypass adblockers.
36-
// See: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-tunneling-to-avoid-ad-blockers.
37-
{ hideSourcemaps: false, tunnelRoute: '/sentry-tunnel' },
38-
);
56+
const sentryConfig = withSentryConfig(
57+
nextConfig,
58+
{ silent: true },
59+
// tunnelRoute set to bypass adblockers.
60+
// See: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-tunneling-to-avoid-ad-blockers.
61+
{ hideSourcemaps: false, tunnelRoute: '/sentry-tunnel' },
62+
);
63+
return sentryConfig;
64+
};

0 commit comments

Comments
 (0)