Skip to content

Commit ef2fc5c

Browse files
committed
Merge branch 'dev' into victor/marketplaceTest
2 parents 8175b35 + c84bdbb commit ef2fc5c

File tree

9 files changed

+241
-61
lines changed

9 files changed

+241
-61
lines changed

__tests__/projects.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const http = require('http')
1111
const {state, projectToSave } = mockData
1212

1313
// save and get projects endpoint testing
14-
xdescribe('Project endpoints tests', () => {
14+
describe('Project endpoints tests', () => {
1515
let server;
1616
beforeAll((done) => {
1717
server = http.createServer(app);
@@ -22,7 +22,7 @@ xdescribe('Project endpoints tests', () => {
2222
server.close(done);
2323
});
2424
// test saveProject endpoint
25-
xdescribe('/saveProject', () => {
25+
describe('/saveProject', () => {
2626
describe('/POST', () => {
2727
it('responds with a status of 200 and json object equal to project sent', () => {
2828
return request(server)
@@ -36,7 +36,7 @@ xdescribe('Project endpoints tests', () => {
3636
});
3737
});
3838
// test getProjects endpoint
39-
xdescribe('/getProjects', () => {
39+
describe('/getProjects', () => {
4040
describe('POST', () => {
4141
it('responds with status of 200 and json object equal to an array of user projects', () => {
4242
return request(server)
@@ -53,7 +53,7 @@ xdescribe('Project endpoints tests', () => {
5353
});
5454
});
5555
// test deleteProject endpoint
56-
xdescribe('/deleteProject', () => {
56+
describe('/deleteProject', () => {
5757
describe('DELETE', () => {
5858
const { name, userId } = projectToSave;
5959
it('responds with status of 200 and json object equal to deleted project', () => {

__tests__/server.test.tsx

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import marketplaceController from '../server/controllers/marketplaceController';
2+
import app from '../server/server';
3+
import mockData from '../mockData';
4+
const request = require('supertest');
5+
const mongoose = require('mongoose');
6+
const mockNext = jest.fn(); // Mock nextFunction
7+
const MONGO_DB = process.env.MONGO_DB_TEST;
8+
const { state, projectToSave, user } = mockData
9+
const PORT = 8080;
10+
11+
beforeAll(async () => {
12+
await mongoose.connect(MONGO_DB, {
13+
useNewUrlParser: true,
14+
useUnifiedTopology: true,
15+
});
16+
});
17+
18+
afterAll(async () => {
19+
await mongoose.connection.close();
20+
});
21+
22+
describe('Server endpoint tests', () => {
23+
it('should pass this test request', async () => {
24+
const response = await request(app).get('/test');
25+
expect(response.status).toBe(200);
26+
expect(response.text).toBe('test request is working');
27+
});
28+
describe('Marketplace endpoint testing', () => {
29+
it('get requests to /getMarketplaceProjects should return an array of projects', async () => {
30+
const response = await request(app).get('/getMarketplaceProjects');
31+
expect(response.status).toBe(200);
32+
expect(Array.isArray(response.body)).toBe(true);
33+
});
34+
it('the return array should be populated with project objects', async () => {
35+
const response = await request(app).get('/getMarketplaceProjects');
36+
expect(response.status).toBe(200);
37+
expect(Array.isArray(response.body)).toBe(true);
38+
});
39+
});
40+
// test saveProject endpoint
41+
describe('/saveProject', () => {
42+
describe('/POST', () => {
43+
it('responds with a status of 200 and json object equal to project sent', async () => {
44+
// const response = await request(app).post('/saveProject').set('Accept', 'application/json').send(projectToSave);
45+
// console.log(response);
46+
// console.log(response.body);
47+
// expect(response.status).toBe(200);
48+
return request(app)
49+
.post('/saveProject')
50+
.set('Accept', 'application/json')
51+
.send(projectToSave)
52+
.expect(200)
53+
.expect('Content-Type', /application\/json/)
54+
.then((res) => expect(res.body.name).toBe(projectToSave.name));
55+
});
56+
// });
57+
});
58+
// test getProjects endpoint
59+
describe('/getProjects', () => {
60+
describe('POST', () => {
61+
it('responds with status of 200 and json object equal to an array of user projects', () => {
62+
return request(app)
63+
.post('/getProjects')
64+
.set('Accept', 'application/json')
65+
.send({ userId: projectToSave.userId })
66+
.expect(200)
67+
.expect('Content-Type', /json/)
68+
.then((res) => {
69+
expect(Array.isArray(res.body)).toBeTruthy;
70+
expect(res.body[0].name).toBe(state.name);
71+
});
72+
});
73+
});
74+
});
75+
// test deleteProject endpoint
76+
describe('/deleteProject', () => {
77+
describe('DELETE', () => {
78+
it('responds with status of 200 and json object equal to deleted project', async () => {
79+
const response: Response = await request(app).post('/getProjects').set('Accept', 'application/json').send({ userId: projectToSave.userId });
80+
const _id: String = response.body[0]._id;
81+
const userId: String = user.username;
82+
console.log(_id, userId);
83+
return request(app)
84+
.delete('/deleteProject')
85+
.set('Content-Type', 'application/json')
86+
.send({ _id, userId })
87+
.expect(200)
88+
.then((res) => expect(res.body.name).toBe(projectToSave.name)); // @Denton might want to check more of these fields
89+
});
90+
});
91+
});
92+
});
93+
});
94+
95+
96+
97+
98+
99+
100+
101+
// describe('marketplaceController Middleware', () => {
102+
// describe('getProjects tests', () => {
103+
// it('should add the projects as an array to res.locals', () => {
104+
// const req = {};
105+
// const res = { locals: {} };
106+
// console.log(marketplaceController.getPublishedProjects);
107+
// console.log(typeof marketplaceController.getPublishedProjects);
108+
// marketplaceController.getPublishedProjects(req, res, mockNext);
109+
// expect(Array.isArray(res.locals.publishedProjects)).toBe(true);
110+
// expect(mockNext).toHaveBeenCalled();
111+
// });
112+
// });
113+
114+
115+
// it('should send an error response if there is an error in the middleware', () => {
116+
// const req = { user: { isAuthenticated: false } };
117+
// const res = mockResponse();
118+
119+
// marketplaceController.authenticateMiddleware(req, res, mockNext);
120+
121+
// expect(res.status).toHaveBeenCalledWith(500);
122+
// expect(res.json).toHaveBeenCalledWith({ err: 'Error in marketplaceController.getPublishedProjects, check server logs for details' });
123+
// });
124+
// });

app/src/components/bottom/CodePreview.tsx

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
import React, { useContext, useState, useRef, useEffect } from 'react';
2-
import AceEditor from 'react-ace';
1+
import 'ace-builds/src-noconflict/ace';
32
import 'ace-builds/src-min-noconflict/ext-searchbox';
43
import 'ace-builds/src-noconflict/mode-javascript';
5-
import 'ace-builds/src-noconflict/theme-monokai';
6-
import 'ace-builds/src-noconflict/theme-github';
7-
import 'ace-builds/src-noconflict/theme-solarized_dark';
8-
import 'ace-builds/src-noconflict/theme-solarized_light';
9-
import 'ace-builds/src-noconflict/theme-monokai';
4+
import 'ace-builds/src-noconflict/theme-dracula';
105
import 'ace-builds/src-noconflict/theme-terminal';
11-
import { Component } from '../../interfaces/Interfaces';
12-
import useResizeObserver from '../../tree/useResizeObserver';
13-
import { unpkgPathPlugin } from '../../plugins/unpkg-path-plugin';
14-
import { fetchPlugin } from '../../plugins/fetch-plugin';
6+
157
import * as esbuild from 'esbuild-wasm';
16-
import {codePreviewSave, codePreviewInput} from "../../redux/reducers/slice/codePreviewSlice";
8+
9+
import React, { useContext, useEffect, useRef, useState } from 'react';
10+
import {
11+
codePreviewInput,
12+
codePreviewSave
13+
} from '../../redux/reducers/slice/codePreviewSlice';
1714
import { useDispatch, useSelector } from 'react-redux';
15+
16+
import AceEditor from 'react-ace';
17+
import { Component } from '../../interfaces/Interfaces';
1818
import { RootState } from '../../redux/store';
19+
import { fetchPlugin } from '../../plugins/fetch-plugin';
20+
import { unpkgPathPlugin } from '../../plugins/unpkg-path-plugin';
21+
import useResizeObserver from '../../tree/useResizeObserver';
1922

2023
const CodePreview: React.FC<{
2124
theme: string | null;
@@ -37,7 +40,7 @@ const CodePreview: React.FC<{
3740
const wrapper = useRef();
3841
const dimensions = useResizeObserver(wrapper);
3942
const { height } = dimensions || 0;
40-
const state = useSelector((store:RootState) => store.appState)
43+
const state = useSelector((store: RootState) => store.appState);
4144
const [, setDivHeight] = useState(0);
4245
let currentComponent = state.components.find(
4346
(elem: Component) => elem.id === state.canvasFocus.componentId
@@ -80,7 +83,7 @@ const CodePreview: React.FC<{
8083
global: 'window'
8184
}
8285
});
83-
dispatch(codePreviewSave(result.outputFiles[0].text))
86+
dispatch(codePreviewSave(result.outputFiles[0].text));
8487
};
8588

8689
return (
@@ -95,15 +98,16 @@ const CodePreview: React.FC<{
9598
>
9699
<AceEditor
97100
mode="javascript"
98-
theme="monokai"
101+
theme="dracula"
99102
width="100%"
100103
height="100%"
101104
onChange={handleChange}
102105
value={input}
103106
name="Code_div"
104107
readOnly={false}
105-
fontSize={18}
108+
fontSize={14}
106109
tabSize={2}
110+
wrapEnabled={true}
107111
setOptions={{
108112
useWorker: false
109113
}}

app/src/components/bottom/StylesEditor.tsx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import React, { useState, useRef } from 'react';
2-
import AceEditor from 'react-ace';
1+
import 'ace-builds/src-noconflict/ace';
32
import 'ace-builds/src-noconflict/mode-css';
4-
import 'ace-builds/src-noconflict/theme-monokai';
5-
import 'ace-builds/src-noconflict/theme-github';
6-
import 'ace-builds/src-noconflict/theme-solarized_dark';
7-
import 'ace-builds/src-noconflict/theme-solarized_light';
8-
import 'ace-builds/src-noconflict/theme-terminal';
9-
import 'ace-builds/src-noconflict/theme-monokai';
3+
import 'ace-builds/src-noconflict/theme-dracula';
104
import 'ace-builds/src-min-noconflict/ext-searchbox';
5+
import 'ace-builds/src-noconflict/ext-language_tools';
6+
7+
import React, { useRef, useState } from 'react';
8+
import { useDispatch, useSelector } from 'react-redux';
9+
10+
import AceEditor from 'react-ace';
1111
import Fab from '@mui/material/Fab';
12+
import { RootState } from '../../redux/store';
1213
import SaveIcon from '@mui/icons-material/Save';
1314
import { updateStylesheet } from '../../redux/reducers/slice/appStateSlice';
14-
import { useDispatch, useSelector } from 'react-redux';
15-
import { RootState } from '../../redux/store';
1615

1716
const StylesEditor: React.FC<{
1817
theme: string | null;
@@ -50,13 +49,13 @@ const StylesEditor: React.FC<{
5049
>
5150
<AceEditor
5251
mode="css"
53-
theme={'monokai'}
52+
theme="dracula"
5453
width="100%"
5554
height="100%"
5655
onChange={handleChange}
5756
value={css}
5857
name="Css_div"
59-
fontSize={16}
58+
fontSize={14}
6059
tabSize={2}
6160
setOptions={{
6261
useWorker: false,

app/src/components/marketplace/MarketplaceCard.tsx

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import imageSrc from '../../../../resources/marketplace_images/marketplace_image
2626
import { red } from '@mui/material/colors';
2727
import { saveProject } from '../../helperFunctions/projectGetSaveDel';
2828
import { useHistory } from 'react-router-dom';
29+
import { openProject } from '../../redux/reducers/slice/appStateSlice';
30+
import MuiAlert, { AlertProps } from '@mui/material/Alert';
31+
import Snackbar from '@mui/material/Snackbar';
2932

3033
interface Project {
3134
forked: String;
@@ -46,6 +49,7 @@ const MarketplaceCard = ({ proj }: { proj: Project }) => {
4649
const history = useHistory();
4750
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
4851
const open = Boolean(anchorEl);
52+
const [alertOpen, setAlertOpen] = React.useState<boolean>(false);
4953
const state = useSelector((store: RootState) => store.appState);
5054
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
5155
setAnchorEl(event.currentTarget);
@@ -56,9 +60,8 @@ const MarketplaceCard = ({ proj }: { proj: Project }) => {
5660
const response = await axios.get(`/cloneProject/${docId}`, {
5761
params: { username: window.localStorage.getItem('username') }
5862
}); //passing in username as a query param is query params
59-
const project = response.data;
60-
console.log('handleClone project', response.data);
61-
alert('Project cloned!');
63+
const project = response.data.project;
64+
setAlertOpen(true);
6265
setAnchorEl(null);
6366
return {
6467
_id: project._id,
@@ -73,10 +76,29 @@ const MarketplaceCard = ({ proj }: { proj: Project }) => {
7376
history.push('/');
7477
dispatch(openProject(project));
7578
};
79+
7680
const handleClose = () => {
7781
setAnchorEl(null);
7882
};
7983

84+
const handleAlertClose = (
85+
event: React.SyntheticEvent | Event,
86+
reason?: string
87+
) => {
88+
if (reason === 'clickaway') {
89+
return;
90+
}
91+
setAlertOpen(false);
92+
setAnchorEl(null);
93+
};
94+
95+
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(function Alert(
96+
props,
97+
ref
98+
) {
99+
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
100+
});
101+
80102
return (
81103
<>
82104
<Card
@@ -143,6 +165,19 @@ const MarketplaceCard = ({ proj }: { proj: Project }) => {
143165
Clone and open
144166
</MenuItem>
145167
</Menu>
168+
<Snackbar
169+
open={alertOpen}
170+
autoHideDuration={3000}
171+
onClose={handleAlertClose}
172+
>
173+
<Alert
174+
onClose={handleAlertClose}
175+
severity="success"
176+
sx={{ width: '100%', color: 'white' }}
177+
>
178+
Project Cloned!
179+
</Alert>
180+
</Snackbar>
146181
</Card>
147182
</>
148183
);

app/src/helperFunctions/projectGetSaveDel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const deleteProject = (project: any): Promise<Object> => {
142142
body
143143
})
144144
.then((res) => res.json())
145-
.then((data) => {
145+
.then((data) => { console.log(data)
146146
return {_id: data._id, name: data.name, published:data.published, ...data.project};
147147
})
148148
.catch((err) => console.log(`Error deleting project ${err}`));

mockData.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const mockObj = {
55
username: 'test',
66
77
password: 'password1!',
8-
userId: '64513ce26f7de07139a03069'
8+
userId: '64f11a47e77f99bf34b08979'
99
},
1010

1111
state: {
@@ -29,7 +29,7 @@ const mockObj = {
2929

3030
projectToSave: {
3131
name: 'super test project',
32-
userId: '60469fc6c435891422b3a84c',
32+
userId: '64f11a47e77f99bf34b08979',
3333
username: 'test',
3434
project: {
3535
name: 'test',

0 commit comments

Comments
 (0)