diff --git a/server/.nyc_output/processinfo/index.json b/server/.nyc_output/processinfo/index.json index c23d26d..7e7c6cb 100644 --- a/server/.nyc_output/processinfo/index.json +++ b/server/.nyc_output/processinfo/index.json @@ -1 +1 @@ -{"processes":{"50560bfc-9d99-4dfb-92f6-1329d287dafe":{"parent":null,"children":[]}},"files":{"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\app.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\database\\index.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\config\\db.config.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\journey.model.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\bill.model.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\utilities.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\location.model.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\user.model.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\routes\\auth.routes.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\controllers\\auth.controller.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\business\\user.business.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\datalayer\\mongo.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\routes\\bill.routes.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\middleware\\auth\\authJwt.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\controllers\\bill.controller.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\business\\bill.business.js":["50560bfc-9d99-4dfb-92f6-1329d287dafe"]},"externalIds":{}} \ No newline at end of file +{"processes":{"076bf10b-2570-48ae-ba89-4c94269b643b":{"parent":null,"children":[]}},"files":{"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\app.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\database\\index.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\config\\db.config.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\journey.model.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\bill.model.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\utilities.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\location.model.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\models\\user.model.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\routes\\auth.routes.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\controllers\\auth.controller.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\business\\user.business.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\datalayer\\mongo.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\routes\\bill.routes.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\middleware\\auth\\authJwt.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\controllers\\bill.controller.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\business\\bill.business.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\routes\\user.routes.js":["076bf10b-2570-48ae-ba89-4c94269b643b"],"E:\\UniWork\\CSSD\\CSSD-Assignment\\server\\controllers\\user.controller.js":["076bf10b-2570-48ae-ba89-4c94269b643b"]},"externalIds":{}} \ No newline at end of file diff --git a/server/app.js b/server/app.js index dabe168..6adc989 100644 --- a/server/app.js +++ b/server/app.js @@ -28,8 +28,9 @@ app.use(cors({ origin: "http://localhost:8080", credentials: true })); */ const authRouter = require("./routes/auth.routes"); const billRouter = require("./routes/bill.routes"); +const userRouter = require("./routes/user.routes"); app.get('/api-docs/swagger.json', (req, res) => res.json(swaggerDocument)); -app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)) +app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); /** * View Engine setup @@ -45,6 +46,7 @@ app.use(cookieParser()); // Configuring the main routes app.use("/auth", authRouter); -app.use("/bill", billRouter) +app.use("/bill", billRouter); +app.use("/user", userRouter); module.exports = app; diff --git a/server/business/user.business.js b/server/business/user.business.js index 38134f7..446bfc3 100644 --- a/server/business/user.business.js +++ b/server/business/user.business.js @@ -47,7 +47,8 @@ module.exports = class UserBusiness { id: user._id, }; }) - .catch(() => {throw httpError(401, "Your email or password is incorrect."); + .catch(() => { + throw httpError(401, "Your email or password is incorrect."); }); } @@ -102,7 +103,22 @@ module.exports = class UserBusiness { throw httpError(404, error.message); }); } -} + + /* + * Find all users and apply any filters + */ + async findAllUsers(queryString) { + const filter = { + offset: queryString.offset, + limit: queryString.limit, + type: queryString.type, + }; + + return this.dataLayer.findAll(filter).catch((error) => { + throw httpError(500, error.message); + }); + } +}; /** * Validates the data in a User. diff --git a/server/controllers/auth.controller.js b/server/controllers/auth.controller.js index 2a5b487..40311d7 100644 --- a/server/controllers/auth.controller.js +++ b/server/controllers/auth.controller.js @@ -10,13 +10,13 @@ exports.login = async (req, res) => { .then((data) => { req.session.token = data.token; req.session.username = data.username; - req.session.role = data.role; + req.session.type = data.type; req.session.id = data.id; res.status(200).send({ message: "Successfully logged in.", username: data.username, - role: data.role, + type: data.type, id: data.id, }); }) diff --git a/server/controllers/user.controller.js b/server/controllers/user.controller.js new file mode 100644 index 0000000..2cfc2d5 --- /dev/null +++ b/server/controllers/user.controller.js @@ -0,0 +1,13 @@ +const UserBusiness = require("../business/user.business"); +const userBusiness = new UserBusiness(); + +/** + * Get all users + */ +exports.getAllUsers = async (req, res) => { + userBusiness.findAllUsers(req.query) + .then((data) => {return res.status(200).send(data)}) + .catch((error) => { + res.status(error.status).send({message: error.message}) + }) +} diff --git a/server/coverage/lcov.info b/server/coverage/lcov.info index 708a31e..1c6967b 100644 --- a/server/coverage/lcov.info +++ b/server/coverage/lcov.info @@ -1,6 +1,6 @@ TN: SF:app.js -FN:31,(anonymous_0) +FN:32,(anonymous_0) FNF:1 FNH:0 FNDA:0,(anonymous_0) @@ -21,7 +21,7 @@ DA:29,1 DA:30,1 DA:31,1 DA:32,1 -DA:37,1 +DA:33,1 DA:38,1 DA:39,1 DA:40,1 @@ -29,11 +29,13 @@ DA:41,1 DA:42,1 DA:43,1 DA:44,1 -DA:47,1 +DA:45,1 DA:48,1 +DA:49,1 DA:50,1 -LF:28 -LH:28 +DA:52,1 +LF:30 +LH:30 BRF:0 BRH:0 end_of_record @@ -42,24 +44,24 @@ SF:utilities.js FN:6,(anonymous_0) FN:10,(anonymous_1) FNF:2 -FNH:0 -FNDA:0,(anonymous_0) -FNDA:0,(anonymous_1) +FNH:2 +FNDA:1,(anonymous_0) +FNDA:3,(anonymous_1) DA:1,1 DA:2,1 DA:3,1 DA:5,1 -DA:7,0 -DA:11,0 -DA:12,0 +DA:7,1 +DA:11,3 +DA:12,3 DA:14,0 DA:17,1 LF:9 -LH:5 -BRDA:11,0,0,0 +LH:8 +BRDA:11,0,0,3 BRDA:11,0,1,0 BRF:2 -BRH:0 +BRH:1 end_of_record TN: SF:business\bill.business.js @@ -71,36 +73,36 @@ FN:34,(anonymous_4) FN:42,(anonymous_5) FN:47,(anonymous_6) FNF:7 -FNH:1 +FNH:5 FNDA:1,(anonymous_0) -FNDA:0,(anonymous_1) +FNDA:5,(anonymous_1) FNDA:0,(anonymous_2) -FNDA:0,(anonymous_3) +FNDA:1,(anonymous_3) FNDA:0,(anonymous_4) -FNDA:0,(anonymous_5) -FNDA:0,(anonymous_6) +FNDA:2,(anonymous_5) +FNDA:1,(anonymous_6) DA:1,1 DA:2,1 DA:3,1 DA:4,1 DA:6,1 DA:9,1 -DA:16,0 -DA:22,0 +DA:16,5 +DA:22,5 DA:25,0 -DA:32,0 +DA:32,1 DA:35,0 -DA:43,0 -DA:46,0 -DA:47,0 +DA:43,2 +DA:46,2 +DA:47,1 LF:14 -LH:6 -BRDA:19,0,0,0 -BRDA:19,0,1,0 -BRDA:20,1,0,0 -BRDA:20,1,1,0 +LH:12 +BRDA:19,0,0,5 +BRDA:19,0,1,4 +BRDA:20,1,0,5 +BRDA:20,1,1,4 BRF:4 -BRH:0 +BRH:4 end_of_record TN: SF:business\user.business.js @@ -108,73 +110,81 @@ FN:8,(anonymous_0) FN:16,(anonymous_1) FN:18,(anonymous_2) FN:50,(anonymous_3) -FN:57,(anonymous_4) -FN:63,(anonymous_5) -FN:71,(anonymous_6) -FN:82,(anonymous_7) -FN:94,(anonymous_8) -FN:97,(anonymous_9) -FN:101,(anonymous_10) -FN:110,isUserDataValid -FNF:12 -FNH:5 -FNDA:1,(anonymous_0) -FNDA:1,(anonymous_1) -FNDA:1,(anonymous_2) -FNDA:0,(anonymous_3) -FNDA:0,(anonymous_4) -FNDA:0,(anonymous_5) -FNDA:0,(anonymous_6) -FNDA:0,(anonymous_7) -FNDA:1,(anonymous_8) -FNDA:1,(anonymous_9) +FN:58,(anonymous_4) +FN:64,(anonymous_5) +FN:72,(anonymous_6) +FN:83,(anonymous_7) +FN:95,(anonymous_8) +FN:98,(anonymous_9) +FN:102,(anonymous_10) +FN:110,(anonymous_11) +FN:117,(anonymous_12) +FN:127,isUserDataValid +FNF:14 +FNH:12 +FNDA:2,(anonymous_0) +FNDA:5,(anonymous_1) +FNDA:5,(anonymous_2) +FNDA:1,(anonymous_3) +FNDA:4,(anonymous_4) +FNDA:3,(anonymous_5) +FNDA:4,(anonymous_6) +FNDA:2,(anonymous_7) +FNDA:5,(anonymous_8) +FNDA:5,(anonymous_9) FNDA:0,(anonymous_10) -FNDA:0,isUserDataValid +FNDA:1,(anonymous_11) +FNDA:0,(anonymous_12) +FNDA:4,isUserDataValid DA:1,1 DA:2,1 DA:3,1 DA:4,1 DA:5,1 DA:7,1 -DA:10,1 -DA:17,1 -DA:19,1 -DA:24,1 -DA:25,0 -DA:31,1 -DA:43,1 -DA:50,0 -DA:58,0 -DA:64,0 -DA:72,0 -DA:73,0 -DA:75,0 -DA:82,0 -DA:83,0 -DA:84,0 -DA:85,0 -DA:86,0 -DA:87,0 -DA:95,1 -DA:99,1 -DA:102,0 -DA:111,0 -LF:29 -LH:14 -BRDA:24,0,0,0 -BRDA:24,0,1,1 -BRDA:72,1,0,0 -BRDA:72,1,1,0 -BRDA:83,2,0,0 -BRDA:83,2,1,0 -BRDA:85,3,0,0 -BRDA:85,3,1,0 -BRDA:111,4,0,0 -BRDA:111,4,1,0 -BRDA:111,4,2,0 -BRDA:111,4,3,0 +DA:10,2 +DA:17,5 +DA:19,5 +DA:24,5 +DA:25,1 +DA:31,4 +DA:43,4 +DA:51,1 +DA:59,4 +DA:65,3 +DA:73,4 +DA:74,1 +DA:76,3 +DA:83,3 +DA:84,2 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,0 +DA:96,5 +DA:100,5 +DA:103,0 +DA:111,1 +DA:117,1 +DA:118,0 +DA:119,0 +DA:128,4 +LF:33 +LH:29 +BRDA:24,0,0,1 +BRDA:24,0,1,4 +BRDA:73,1,0,1 +BRDA:73,1,1,3 +BRDA:84,2,0,1 +BRDA:84,2,1,1 +BRDA:86,3,0,1 +BRDA:86,3,1,0 +BRDA:128,4,0,4 +BRDA:128,4,1,4 +BRDA:128,4,2,3 +BRDA:128,4,3,3 BRF:12 -BRH:1 +BRH:11 end_of_record TN: SF:config\db.config.js @@ -196,33 +206,33 @@ FN:34,(anonymous_4) FN:39,(anonymous_5) FN:47,(anonymous_6) FNF:7 -FNH:3 -FNDA:1,(anonymous_0) -FNDA:1,(anonymous_1) -FNDA:0,(anonymous_2) -FNDA:0,(anonymous_3) -FNDA:0,(anonymous_4) -FNDA:0,(anonymous_5) +FNH:7 +FNDA:5,(anonymous_0) +FNDA:4,(anonymous_1) +FNDA:1,(anonymous_2) +FNDA:4,(anonymous_3) +FNDA:1,(anonymous_4) +FNDA:3,(anonymous_5) FNDA:1,(anonymous_6) DA:1,1 DA:2,1 DA:7,1 -DA:8,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:16,1 -DA:24,0 +DA:8,5 +DA:11,4 +DA:12,4 +DA:13,4 +DA:14,4 +DA:16,4 +DA:24,1 DA:31,1 -DA:32,0 -DA:35,0 -DA:40,0 +DA:32,4 +DA:35,1 +DA:40,3 DA:47,1 DA:48,1 DA:49,1 LF:17 -LH:13 +LH:17 BRF:0 BRH:0 end_of_record @@ -238,31 +248,52 @@ FN:27,(anonymous_6) FN:29,(anonymous_7) FN:30,(anonymous_8) FNF:9 -FNH:0 -FNDA:0,(anonymous_0) -FNDA:0,(anonymous_1) +FNH:7 +FNDA:5,(anonymous_0) +FNDA:5,(anonymous_1) FNDA:0,(anonymous_2) -FNDA:0,(anonymous_3) -FNDA:0,(anonymous_4) +FNDA:1,(anonymous_3) +FNDA:1,(anonymous_4) FNDA:0,(anonymous_5) -FNDA:0,(anonymous_6) -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) +FNDA:2,(anonymous_6) +FNDA:1,(anonymous_7) +FNDA:1,(anonymous_8) DA:1,1 DA:2,1 DA:7,1 -DA:8,0 -DA:9,0 +DA:8,5 +DA:9,5 DA:11,0 DA:18,1 -DA:19,0 -DA:20,0 +DA:19,1 +DA:20,1 DA:21,0 DA:27,1 -DA:28,0 -DA:29,0 -DA:30,0 +DA:28,2 +DA:29,1 +DA:30,1 LF:14 +LH:12 +BRF:0 +BRH:0 +end_of_record +TN: +SF:controllers\user.controller.js +FN:7,(anonymous_0) +FN:9,(anonymous_1) +FN:10,(anonymous_2) +FNF:3 +FNH:2 +FNDA:1,(anonymous_0) +FNDA:1,(anonymous_1) +FNDA:0,(anonymous_2) +DA:1,1 +DA:2,1 +DA:7,1 +DA:8,1 +DA:9,1 +DA:11,0 +LF:6 LH:5 BRF:0 BRH:0 @@ -316,36 +347,45 @@ TN: SF:datalayer\mongo.js FN:2,(anonymous_0) FN:10,(anonymous_1) -FN:15,(anonymous_2) -FN:16,(anonymous_3) -FN:25,(anonymous_4) -FN:34,(anonymous_5) -FN:41,(anonymous_6) -FN:48,(anonymous_7) -FN:51,(anonymous_8) -FNF:9 -FNH:2 -FNDA:2,(anonymous_0) -FNDA:0,(anonymous_1) -FNDA:0,(anonymous_2) -FNDA:0,(anonymous_3) -FNDA:0,(anonymous_4) +FN:16,(anonymous_2) +FN:17,(anonymous_3) +FN:23,(anonymous_4) +FN:28,(anonymous_5) +FN:29,(anonymous_6) +FN:38,(anonymous_7) +FN:48,(anonymous_8) +FN:55,(anonymous_9) +FN:62,(anonymous_10) +FN:66,(anonymous_11) +FNF:12 +FNH:12 +FNDA:3,(anonymous_0) +FNDA:5,(anonymous_1) +FNDA:5,(anonymous_2) +FNDA:5,(anonymous_3) +FNDA:1,(anonymous_4) FNDA:1,(anonymous_5) -FNDA:0,(anonymous_6) -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:4,2 -DA:11,0 -DA:16,0 -DA:17,0 -DA:26,0 -DA:35,1 -DA:42,0 -DA:49,0 -DA:51,0 -DA:56,1 -LF:10 -LH:3 +FNDA:1,(anonymous_6) +FNDA:1,(anonymous_7) +FNDA:5,(anonymous_8) +FNDA:3,(anonymous_9) +FNDA:2,(anonymous_10) +FNDA:1,(anonymous_11) +DA:4,3 +DA:11,5 +DA:17,5 +DA:18,5 +DA:24,1 +DA:29,1 +DA:30,1 +DA:39,1 +DA:49,5 +DA:56,3 +DA:63,2 +DA:67,1 +DA:72,1 +LF:13 +LH:13 BRF:0 BRH:0 end_of_record @@ -353,34 +393,43 @@ TN: SF:middleware\auth\authJwt.js FN:4,(anonymous_0) FN:12,(anonymous_1) -FNF:2 -FNH:0 -FNDA:0,(anonymous_0) -FNDA:0,(anonymous_1) +FN:26,(anonymous_2) +FNF:3 +FNH:3 +FNDA:14,(anonymous_0) +FNDA:10,(anonymous_1) +FNDA:4,(anonymous_2) DA:1,1 DA:4,1 -DA:5,0 -DA:6,0 -DA:10,0 -DA:12,0 -DA:13,0 +DA:5,14 +DA:6,4 +DA:10,10 +DA:12,10 +DA:13,10 DA:14,0 -DA:18,0 -DA:19,0 -DA:20,0 -DA:21,0 -DA:22,0 +DA:18,10 +DA:19,10 +DA:20,10 +DA:21,10 +DA:22,10 +DA:26,1 +DA:27,4 +DA:28,4 +DA:29,2 +DA:34,2 DA:37,1 -LF:14 -LH:3 -BRDA:5,0,0,0 -BRDA:5,0,1,0 -BRDA:5,1,0,0 -BRDA:5,1,1,0 +LF:19 +LH:18 +BRDA:5,0,0,4 +BRDA:5,0,1,10 +BRDA:5,1,0,14 +BRDA:5,1,1,14 BRDA:13,2,0,0 -BRDA:13,2,1,0 -BRF:6 -BRH:0 +BRDA:13,2,1,10 +BRDA:28,3,0,2 +BRDA:28,3,1,2 +BRF:8 +BRH:7 end_of_record TN: SF:models\bill.model.js @@ -481,3 +530,18 @@ LH:8 BRF:0 BRH:0 end_of_record +TN: +SF:routes\user.routes.js +FNF:0 +FNH:0 +DA:1,1 +DA:2,1 +DA:3,1 +DA:6,1 +DA:9,1 +DA:11,1 +LF:6 +LH:6 +BRF:0 +BRH:0 +end_of_record diff --git a/server/database/seed.js b/server/database/seed.js index 4d010d0..879f814 100644 --- a/server/database/seed.js +++ b/server/database/seed.js @@ -34,6 +34,13 @@ const users = [ password: bcrypt.hashSync("test1", 8), type: "Driver", }, + { + _id: "123456789111", + username: "operator_username", + email: "operator@email.com", + password: bcrypt.hashSync("test1", 8), + type: "Toll Operator", + } ]; const locations = [ diff --git a/server/datalayer/mongo.js b/server/datalayer/mongo.js index 2bc8eae..6bc76a2 100644 --- a/server/datalayer/mongo.js +++ b/server/datalayer/mongo.js @@ -8,33 +8,49 @@ class DataLayer { * Find all records in the database. */ async findAllAndPopulate(filter, populateFilter) { - return this.model.find(JSON.parse(JSON.stringify(filter))) - .limit(filter.limit) - .skip(filter.offset * filter.limit) - .populate(JSON.parse(JSON.stringify(populateFilter))) - .then((bills) => { - return this.model.countDocuments().then((count) => { - return {bills: bills, count: count} - }) - }) + return this.model + .find(JSON.parse(JSON.stringify(filter))) + .limit(filter.limit) + .skip(filter.offset * filter.limit) + .populate(JSON.parse(JSON.stringify(populateFilter))) + .then((bills) => { + return this.model.countDocuments().then((count) => { + return { bills: bills, count: count }; + }); + }); + } + /** + * Find all users in the database. + */ + async findAll(filter) { + return this.model + .find(JSON.parse(JSON.stringify(filter))) + .limit(filter.limit) + .skip(filter.offset * filter.limit) + .then((users) => { + return this.model.countDocuments().then((count) => { + return { users: users, count: count }; + }); + }); } /** * Find all records in the database. */ async findByPropertyAndPopulate(id, populateFilter) { - return this.model.findById(id) - .orFail(new Error("Record can't be found in the database.")) - .populate(JSON.parse(JSON.stringify(populateFilter))) + return this.model + .findById(id) + .orFail(new Error("Record can't be found in the database.")) + .populate(JSON.parse(JSON.stringify(populateFilter))); } - + /** * Find a record by property in the database. */ async findByProperty(propertyToFind) { return this.model.find(propertyToFind); } - + /** * Create and save the record to the database. */ @@ -46,10 +62,12 @@ class DataLayer { * Update and save the record to the database. */ async update(recordId, recordToUpdate) { - return this.model.findByIdAndUpdate(recordId, recordToUpdate) - .orFail(new Error("Bill can't be found in the database.")) - .catch(error => {throw new Error(error.message)}); - + return this.model + .findByIdAndUpdate(recordId, recordToUpdate) + .orFail(new Error("Bill can't be found in the database.")) + .catch((error) => { + throw new Error(error.message); + }); } } diff --git a/server/middleware/auth/authJwt.js b/server/middleware/auth/authJwt.js index 07efcd4..0b8732e 100644 --- a/server/middleware/auth/authJwt.js +++ b/server/middleware/auth/authJwt.js @@ -22,19 +22,19 @@ const checkJwtToken = (req, res, next) => { return next(); }); }; - -// const isOperator = (req, res, next) => { -// const type = req.type; -// if (type !== "Toll Operator") { -// return res.status(403).send({ -// message: -// "Unauthorized: You not do have permission to view this page.", -// }); -// } -// return next(); -// }; +// Check if the active user is an operator +const isOperator = (req, res, next) => { + const type = req.type; + if (type !== "Toll Operator") { + return res.status(403).send({ + message: + "Unauthorized: You not do have permission to view this page.", + }); + } + return next(); +}; module.exports = { - checkJwtToken - //isOperator, + checkJwtToken, + isOperator, }; diff --git a/server/models/user.model.js b/server/models/user.model.js index 4f0b158..4d1cbbe 100644 --- a/server/models/user.model.js +++ b/server/models/user.model.js @@ -22,7 +22,7 @@ module.exports = (mongoose) => { required: [true, "You must supply the user's role."], enum: { values: ["Driver", "Toll Operator"], - message: "Type is not valid. Must be 'Driver'.", + message: "Type is not valid. Must be 'Driver' or 'Toll Operator'.", }, }, }); diff --git a/server/routes/user.routes.js b/server/routes/user.routes.js new file mode 100644 index 0000000..1f326a0 --- /dev/null +++ b/server/routes/user.routes.js @@ -0,0 +1,11 @@ +const express = require("express"); +const router = express.Router(); +const { checkJwtToken, isOperator } = require("../middleware/auth/authJwt"); + +// Get the user controller +const userController = require("../controllers/user.controller"); + +// Get All Users +router.get("/", checkJwtToken, isOperator, userController.getAllUsers); + +module.exports = router; diff --git a/server/test/integration/bill.controller.test.js b/server/test/integration/bill.controller.test.js index a601ecf..cdfd0f5 100644 --- a/server/test/integration/bill.controller.test.js +++ b/server/test/integration/bill.controller.test.js @@ -8,7 +8,6 @@ let authCookie; let authCookieSig; before(function (done) { - chai.request(server) .post("/auth/login") .send({ @@ -95,7 +94,7 @@ describe("Testing /bill paths", () => { it("Should get bill by id", (done) => { // Arrange - const billId = '123456789105'; + const billId = "123456789105"; const url = `/bill/${billId}`; // Act @@ -107,10 +106,7 @@ describe("Testing /bill paths", () => { // Assert res.should.have.status(200); res.should.be.a("object"); - res.body.should.haveOwnProperty( - "cost", - 72.93887106726764 - ); + res.body.should.haveOwnProperty("cost", 72.93887106726764); res.body.should.haveOwnProperty("paid", false); res.body.driver.should.haveOwnProperty( "username", @@ -120,10 +116,7 @@ describe("Testing /bill paths", () => { "email", "test@email.com" ); - res.body.driver.should.haveOwnProperty( - "type", - "Driver" - ); + res.body.driver.should.haveOwnProperty("type", "Driver"); res.body.journey.should.haveOwnProperty( "regNumber", "test_reg_number" @@ -443,7 +436,7 @@ describe("Testing /bill paths", () => { it("Should get a bill by id but does not have authorisation", (done) => { // Arrange - const billId = '123456789105' + const billId = "123456789105"; const url = `/bill/${billId}`; // Act @@ -482,7 +475,7 @@ describe("Testing /bill paths", () => { it("Should pay for a bill but does not have authorisation", (done) => { // Arrange - const billId = '123456789105'; + const billId = "123456789105"; const requestBody = { paid: true, }; @@ -506,7 +499,7 @@ describe("Testing /bill paths", () => { it("Should gets a bill by id, but cookie has expired", (done) => { // Arrange - const billId = '123456789105' + const billId = "123456789105"; const url = `/bill/${billId}`; // Act @@ -523,5 +516,4 @@ describe("Testing /bill paths", () => { done(); }); }); - }); diff --git a/server/test/integration/user.controller.test.js b/server/test/integration/user.controller.test.js new file mode 100644 index 0000000..386d7ac --- /dev/null +++ b/server/test/integration/user.controller.test.js @@ -0,0 +1,78 @@ +let chai = require("chai"); +let chaiHttp = require("chai-http"); +const { ListIndexesCursor } = require("mongoose/node_modules/mongodb"); +let server = require("../../app"); +let should = chai.should(); +chai.use(chaiHttp); + +let authCookie; +let authCookieSig; + +before(function (done) { + chai.request(server) + .post("/auth/login") + .send({ + email: "operator@email.com", + password: "test1", + }) + .end((err, res) => { + authCookie = res.headers["set-cookie"].pop().split(";")[0]; + authCookieSig = res.headers["set-cookie"].pop().split(";")[0]; + done(); + }); +}); + +describe("Testing /user paths", () => { + it("Should get all users", (done) => { + // Arrange + const limit = "10"; + const offset = "0"; + const url = `/user?limit=${limit}&offset=${offset}`; + // Act + chai.request(server) + .get(url) + .set("Cookie", authCookie + "; " + authCookieSig) + .end((err, res) => { + // Assert + res.should.have.status(200); + res.should.be.a("object"); + + done(); + }); + }); +}); + +describe("Testing /user paths", () => { + before(function (done) { + chai.request(server) + .post("/auth/login") + .send({ + email: "test@email.com", + password: "test1", + }) + .end((err, res) => { + authCookie = res.headers["set-cookie"].pop().split(";")[0]; + authCookieSig = res.headers["set-cookie"].pop().split(";")[0]; + done(); + }); + }); + + it("Should not get all users", (done) => { + // Arrange + const url = "/user/"; + // Act + chai.request(server) + .get(url) + .set("Cookie", authCookie + "; " + authCookieSig) + .end((err, res) => { + // Assert + res.should.have.status(403); + res.should.be.a("object"); + res.body.message.should.be.eql( + "Unauthorized: You not do have permission to view this page." + ); + + done(); + }); + }); +}); diff --git a/server/test/unit/auth.test.js b/server/test/unit/auth.test.js new file mode 100644 index 0000000..17cc680 --- /dev/null +++ b/server/test/unit/auth.test.js @@ -0,0 +1,58 @@ +let chai = require("chai"); +const { isOperator } = require("../../middleware/auth/authJwt"); +let should = chai.should(); +let expect = chai.expect; + +describe("Testing auth functions", () => { + it("Testing isOperator with user Driver", (done) => { + // Arrange + let called = false; + let res = { + send: function (response) { + expect(response.message).to.be.equal( + "Unauthorized: You not do have permission to view this page." + ); + }, + status: function () { + return this; + }, + }; + let next = function () { + called = true; + }; + + // Act + isOperator({ type: "Driver" }, res, next); + + // Assert + expect(called).to.be.false; + + done(); + }); + + it("Testing isOperator with user Toll Operator", (done) => { + // Arrange + let called = false; + let res = { + send: function (response) { + expect(response.message).to.be.equal( + "Unauthorized: You not do have permission to view this page." + ); + }, + status: function () { + return this; + }, + }; + let next = function () { + called = true; + }; + + // Act + isOperator({ type: "Toll Operator" }, res, next); + + // Assert + expect(called).to.be.true; + + done(); + }); +}); diff --git a/ui/cypress/support/commands.js b/ui/cypress/support/commands.js index f55e0cd..4abd6b2 100644 --- a/ui/cypress/support/commands.js +++ b/ui/cypress/support/commands.js @@ -23,10 +23,25 @@ // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -Cypress.Commands.add('login', (email, password) => { - cy.visit('/') - cy.get('#email').type(email) - cy.get('#password').type(password) - cy.get('#login').click() - cy.url().should('contain', '/my-bills') - }) \ No newline at end of file +Cypress.Commands.add("login", (email, password) => { + cy.visit("/"); + cy.get("#email").type(email); + cy.get("#password").type(password); + cy.get("#login").click(); + cy.url().should("contain", "/my-bills"); +}); + +Cypress.Commands.add("adminLogin", (email, password) => { + cy.visit("/"); + cy.get("#email").type(email); + cy.get("#password").type(password); + cy.get("#login").click(); + cy.url().should("contain", "/view-users"); +}); + +Cypress.Commands.add("signOut", () => { + cy.visit("/"); + cy.get("#profile").click(); + cy.get("#signOut").click(); + cy.url().should("contain", "/login"); +}); diff --git a/ui/src/api/api.js b/ui/src/api/api.js index abcaf2f..6729754 100644 --- a/ui/src/api/api.js +++ b/ui/src/api/api.js @@ -27,17 +27,37 @@ const api = class Api { }); } + async getAllUsers(queryString) { + const query = { + limit: queryString.limit, + offset: queryString.offset, + type: queryString.type, + }; + + return axios + .get(`${this.baseUrl}/user/`, { + params: JSON.parse(JSON.stringify(query)), + withCredentials: true, + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + throw error; + }); + } + async getBillById(billId) { return axios - .get(`${this.baseUrl}/bill/${billId}`, { - withCredentials: true, - }) - .then((response) => { - return response.data; - }) - .catch((error) => { - throw error; - }); + .get(`${this.baseUrl}/bill/${billId}`, { + withCredentials: true, + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + throw error; + }); } async payBill(billId) { diff --git a/ui/src/auth/index.js b/ui/src/auth/index.js index 1557b3e..5e9c61f 100644 --- a/ui/src/auth/index.js +++ b/ui/src/auth/index.js @@ -15,7 +15,7 @@ export const isAuthenticated = (to, from, next) => { * Check if the user transitioning the route is an admin. */ export const isOperator = (to, from, next) => { - if (store.getters.user.type == "Operator") { + if (store.getters.user.type == "Toll Operator") { next(); } else { next({ path: "/forbidden" }); diff --git a/ui/src/components/navbar.vue b/ui/src/components/navbar.vue index 8cfb66c..c8f420a 100644 --- a/ui/src/components/navbar.vue +++ b/ui/src/components/navbar.vue @@ -4,7 +4,11 @@ id="navbar" v-if="loggedIn" > - + Self Service Portal LogoSelf Service Portal - + support icon{{ username }} - Sign Out + Sign Out @@ -132,6 +144,17 @@ export default Vue.extend({ }); }); }, + + /** + * Return to the landing page depending on the user that is logged in. + */ + goToHome() { + if (store.getters.user.type == "Toll Operator") { + this.$router.push("view-users"); + } else { + this.$router.push("my-bills"); + } + }, }, computed: { /** diff --git a/ui/src/router/router.js b/ui/src/router/router.js index 23157f6..00172e7 100644 --- a/ui/src/router/router.js +++ b/ui/src/router/router.js @@ -4,8 +4,9 @@ import MyBills from "@/views/MyBills"; import PayBill from "@/views/PayBill"; import Login from "@/views/Login"; import Register from "@/views/Register"; -import { isAuthenticated, isLoggedOut } from "../auth"; +import { isAuthenticated, isLoggedOut, isOperator } from "../auth"; import Help from "@/views/Help"; +import ViewUsers from "@/views/ViewUsers"; /** * Import Vue Router. @@ -38,6 +39,15 @@ const routes = [ }, beforeEnter: isAuthenticated, }, + { + path: "/view-users", + name: "ViewUsers", + component: ViewUsers, + meta: { + title: "View Users", + }, + beforeEnter: isOperator, + }, { path: "/login", name: "Login", diff --git a/ui/src/views/Login.vue b/ui/src/views/Login.vue index 7e70a7c..f0d8d1c 100644 --- a/ui/src/views/Login.vue +++ b/ui/src/views/Login.vue @@ -48,8 +48,15 @@ export default { username: data.username, type: data.type, }); - - this.$router.push("my-bills"); + + if(store.getters.user.type == 'Toll Operator') + { + this.$router.push("view-users"); + } + else + { + this.$router.push("my-bills"); + } }) .catch((error) => { this.$bvToast.toast(error.message, { diff --git a/ui/src/views/MyBills.vue b/ui/src/views/MyBills.vue index 969aed1..067a2ff 100644 --- a/ui/src/views/MyBills.vue +++ b/ui/src/views/MyBills.vue @@ -1,52 +1,104 @@  \ No newline at end of file diff --git a/ui/tests/e2e/tests/mybills.spec.js b/ui/tests/e2e/tests/mybills.spec.js index 33bef8e..07e0fcc 100644 --- a/ui/tests/e2e/tests/mybills.spec.js +++ b/ui/tests/e2e/tests/mybills.spec.js @@ -1,44 +1,54 @@ -describe('My Bills Tests', () => { - - before(() => { - cy.login('test@email.com', 'test1') - }) - - it('displays two rows in the bills table', () => { - //Act - cy.visit('/my-bills') - - //Assert - cy.get('#bills-table').find('tbody tr').should('have.length', 2) - }) - - it('Entry Location filters the my bills table', () => { - //Act - cy.visit('/my-bills') - cy.get('#bills-table').get('#entry-location-filter').type('Entry Location') - - //Assert - cy.get('#bills-table').find('tbody tr').should('have.text', 'No bills match the filter.') - }) - - - it('Exit Location filters the my bills table', () => { - //Act - cy.visit('/my-bills') - cy.get('#bills-table').get('#exit-location-filter').type('Exit Location') - - //Assert - cy.get('#bills-table').find('tbody tr').should('have.text', 'No bills match the filter.') - }) - - it('Car Registration Number filters the my bills table', () => { - //Act - cy.visit('/my-bills') - cy.get('#bills-table').get('#car-registration-filter').type('Car Registration Number') - - //Assert - cy.get('#bills-table').find('tbody tr').should('have.text', 'No bills match the filter.') - }) - - //TODO: TEST PAGINATION -}) +describe("My Bills Tests", () => { + before(() => { + cy.login("test@email.com", "test1"); + }); + + it("displays two rows in the bills table", () => { + // Act + cy.visit("/my-bills"); + + // Assert + cy.get("#bills-table").find("tbody tr").should("have.length", 2); + }); + + it("Entry Location filters the my bills table", () => { + // Act + cy.visit("/my-bills"); + cy.get("#bills-table") + .get("#entry-location-filter") + .type("Entry Location"); + + // Assert + cy.get("#bills-table") + .find("tbody tr") + .should("have.text", "No bills match the filter."); + }); + + it("Exit Location filters the my bills table", () => { + // Act + cy.visit("/my-bills"); + cy.get("#bills-table") + .get("#exit-location-filter") + .type("Exit Location"); + + // Assert + cy.get("#bills-table") + .find("tbody tr") + .should("have.text", "No bills match the filter."); + }); + + it("Car Registration Number filters the my bills table", () => { + // Act + cy.visit("/my-bills"); + cy.get("#bills-table") + .get("#car-registration-filter") + .type("Car Registration Number"); + + // Assert + cy.get("#bills-table") + .find("tbody tr") + .should("have.text", "No bills match the filter."); + }); + + //TODO: TEST PAGINATION +}); diff --git a/ui/tests/e2e/tests/navbar.spec.js b/ui/tests/e2e/tests/navbar.spec.js index 0d9a95a..2173e0e 100644 --- a/ui/tests/e2e/tests/navbar.spec.js +++ b/ui/tests/e2e/tests/navbar.spec.js @@ -1,304 +1,331 @@ -describe('Navbar Tests', () => { - - before(() => { - cy.login('test@email.com', 'test1') - }) - - context('Languages Dropdown', () => { - it('shows 23 languages when the languages dropdown is clicked', () => { - //Act - cy.visit('/my-bills') - cy.get('#languages').click() - - //Assert - cy.get('#languages ul li').should('have.length', 23) - }) - - it('selected language changes to Bulgarian when the Bulgarian option is selected', () => { - //Act - cy.get('#Bulgarian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Bulgarian') - }) - - it('selected language changes to Czech when the Czech option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Czech').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Czech') - }) - - it('selected language changes to Danish when the Danish option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Danish').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Danish') - }) - - it('selected language changes to Dutch when the Dutch option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Dutch').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Dutch') - }) - - it('selected language changes to English when the English option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#English').click() - - //Assert - cy.get('#selected-language').should('have.text', 'English') - }) - - it('selected language changes to Estonian when the Estonian option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Estonian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Estonian') - }) - - it('selected language changes to Finnish when the Finnish option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Finnish').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Finnish') - }) - - it('selected language changes to French when the French option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#French').click() - - //Assert - cy.get('#selected-language').should('have.text', 'French') - }) - - it('selected language changes to German when the German option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#German').click() - - //Assert - cy.get('#selected-language').should('have.text', 'German') - }) - - it('selected language changes to Greek when the Greek option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Greek').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Greek') - }) - - it('selected language changes to Hungarian when the Hungarian option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Hungarian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Hungarian') - }) - - it('selected language changes to Irish when the Irish option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Irish').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Irish') - }) - - it('selected language changes to Italian when the Italian option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Italian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Italian') - }) - - it('selected language changes to Latvian when the Latvian option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Latvian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Latvian') - }) - - it('selected language changes to Lithuanian when the Lithuanian option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Lithuanian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Lithuanian') - }) - - it('selected language changes to Maltese when the Maltese option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Maltese').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Maltese') - }) - - it('selected language changes to Polish when the Polish option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Polish').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Polish') - }) - - it('selected language changes to Portuguese when the Portuguese option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Portuguese').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Portuguese') - }) - - it('selected language changes to Romanian when the Romanian option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Romanian').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Romanian') - }) - - it('selected language changes to Slovak when the Slovak option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Slovak').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Slovak') - }) - - it('selected language changes to Slovene when the Slovene option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Slovene').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Slovene') - }) - - it('selected language changes to Spanish when the Spanish option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Spanish').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Spanish') - }) - - it('selected language changes to Swedish when the Swedish option is selected', () => { - //Act - cy.get('#languages').click() - cy.get('#Swedish').click() - - //Assert - cy.get('#selected-language').should('have.text', 'Swedish') - }) - }) - - - context('Profile Dropdown', () => { - it('shows sign out when the profile dropdown is clicked', () => { - //Act - cy.get('#profile').click() - - //Assert - cy.get('#profile ul li').should('have.text', 'Sign Out') - }) - }) - - - context('Currency Dropdown', () => { - it('shows 6 currencies when the currency dropdown is clicked', () => { - //Act - cy.get('#currencies').click() - - //Assert - cy.get('#currencies ul li').should('have.length', 6) - }) - - it('cost doesnt change when NOK is selected in the currency drop down', () => { - //Act - cy.get('#NOK').click() - - //Assert - cy.get('#selected-currency').should('have.text', 'NOK') - cy.get('#bills-table').find('tbody tr').first().get('td').eq(4).should('have.text', ' NOK 72.94 ') - }) - - it('cost updates to 75.86 when SEK is selected in the currency drop down', () => { - //Act - cy.get('#currencies').click() - cy.get('#SEK').click() - - //Assert - cy.get('#selected-currency').should('have.text', 'SEK') - cy.get('#bills-table').find('tbody tr').first().get('td').eq(4).should('have.text', ' SEK 75.86 ') - }) - - it('cost updates to 1,042 when ISK is selected in the currency drop down', () => { - //Act - cy.get('#currencies').click() - cy.get('#ISK').click() - - //Assert - cy.get('#selected-currency').should('have.text', 'ISK') - cy.get('#bills-table').find('tbody tr').first().get('td').eq(4).should('have.text', ' ISK 1,042 ') - }) - - it('cost updates to 53.97 when DKK is selected in the currency drop down', () => { - //Act - cy.get('#currencies').click() - cy.get('#DKK').click() - - //Assert - cy.get('#selected-currency').should('have.text', 'DKK') - cy.get('#bills-table').find('tbody tr').first().get('td').eq(4).should('have.text', ' DKK 53.97 ') - }) - - it('cost updates to 6.13 when GBP is selected in the currency drop down', () => { - //Act - cy.get('#currencies').click() - cy.get('#GBP').click() - - //Assert - cy.get('#selected-currency').should('have.text', 'GBP') - cy.get('#bills-table').find('tbody tr').first().get('td').eq(4).should('have.text', ' £6.13 ') - }) - - it('cost updates to 7.29 when EUR is selected in the currency drop down', () => { - //Act - cy.get('#currencies').click() - cy.get('#EUR').click() - - //Assert - cy.get('#selected-currency').should('have.text', 'EUR') - cy.get('#bills-table').find('tbody tr').first().get('td').eq(4).should('have.text', ' €7.29 ') - }) - }) -}) +describe("Navbar Tests", () => { + before(() => { + cy.login("test@email.com", "test1"); + }); + + context("Languages Dropdown", () => { + it("shows 23 languages when the languages dropdown is clicked", () => { + // Act + cy.visit("/my-bills"); + cy.get("#languages").click(); + + // Assert + cy.get("#languages ul li").should("have.length", 23); + }); + + it("selected language changes to Bulgarian when the Bulgarian option is selected", () => { + // Act + cy.get("#Bulgarian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Bulgarian"); + }); + + it("selected language changes to Czech when the Czech option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Czech").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Czech"); + }); + + it("selected language changes to Danish when the Danish option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Danish").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Danish"); + }); + + it("selected language changes to Dutch when the Dutch option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Dutch").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Dutch"); + }); + + it("selected language changes to English when the English option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#English").click(); + + // Assert + cy.get("#selected-language").should("have.text", "English"); + }); + + it("selected language changes to Estonian when the Estonian option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Estonian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Estonian"); + }); + + it("selected language changes to Finnish when the Finnish option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Finnish").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Finnish"); + }); + + it("selected language changes to French when the French option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#French").click(); + + // Assert + cy.get("#selected-language").should("have.text", "French"); + }); + + it("selected language changes to German when the German option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#German").click(); + + // Assert + cy.get("#selected-language").should("have.text", "German"); + }); + + it("selected language changes to Greek when the Greek option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Greek").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Greek"); + }); + + it("selected language changes to Hungarian when the Hungarian option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Hungarian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Hungarian"); + }); + + it("selected language changes to Irish when the Irish option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Irish").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Irish"); + }); + + it("selected language changes to Italian when the Italian option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Italian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Italian"); + }); + + it("selected language changes to Latvian when the Latvian option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Latvian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Latvian"); + }); + + it("selected language changes to Lithuanian when the Lithuanian option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Lithuanian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Lithuanian"); + }); + + it("selected language changes to Maltese when the Maltese option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Maltese").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Maltese"); + }); + + it("selected language changes to Polish when the Polish option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Polish").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Polish"); + }); + + it("selected language changes to Portuguese when the Portuguese option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Portuguese").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Portuguese"); + }); + + it("selected language changes to Romanian when the Romanian option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Romanian").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Romanian"); + }); + + it("selected language changes to Slovak when the Slovak option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Slovak").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Slovak"); + }); + + it("selected language changes to Slovene when the Slovene option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Slovene").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Slovene"); + }); + + it("selected language changes to Spanish when the Spanish option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Spanish").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Spanish"); + }); + + it("selected language changes to Swedish when the Swedish option is selected", () => { + // Act + cy.get("#languages").click(); + cy.get("#Swedish").click(); + + // Assert + cy.get("#selected-language").should("have.text", "Swedish"); + }); + }); + + context("Profile Dropdown", () => { + it("shows sign out when the profile dropdown is clicked", () => { + // Act + cy.get("#profile").click(); + + // Assert + cy.get("#profile ul li").should("have.text", "Sign Out"); + }); + }); + + context("Currency Dropdown", () => { + it("shows 6 currencies when the currency dropdown is clicked", () => { + // Act + cy.get("#currencies").click(); + + // Assert + cy.get("#currencies ul li").should("have.length", 6); + }); + + it("cost doesnt change when NOK is selected in the currency drop down", () => { + // Act + cy.get("#NOK").click(); + + // Assert + cy.get("#selected-currency").should("have.text", "NOK"); + cy.get("#bills-table") + .find("tbody tr") + .first() + .get("td") + .eq(4) + .should("have.text", " NOK 72.94 "); + }); + + it("cost updates to 75.86 when SEK is selected in the currency drop down", () => { + // Act + cy.get("#currencies").click(); + cy.get("#SEK").click(); + + // Assert + cy.get("#selected-currency").should("have.text", "SEK"); + cy.get("#bills-table") + .find("tbody tr") + .first() + .get("td") + .eq(4) + .should("have.text", " SEK 75.86 "); + }); + + it("cost updates to 1,042 when ISK is selected in the currency drop down", () => { + // Act + cy.get("#currencies").click(); + cy.get("#ISK").click(); + + // Assert + cy.get("#selected-currency").should("have.text", "ISK"); + cy.get("#bills-table") + .find("tbody tr") + .first() + .get("td") + .eq(4) + .should("have.text", " ISK 1,042 "); + }); + + it("cost updates to 53.97 when DKK is selected in the currency drop down", () => { + // Act + cy.get("#currencies").click(); + cy.get("#DKK").click(); + + // Assert + cy.get("#selected-currency").should("have.text", "DKK"); + cy.get("#bills-table") + .find("tbody tr") + .first() + .get("td") + .eq(4) + .should("have.text", " DKK 53.97 "); + }); + + it("cost updates to 6.13 when GBP is selected in the currency drop down", () => { + // Act + cy.get("#currencies").click(); + cy.get("#GBP").click(); + + // Assert + cy.get("#selected-currency").should("have.text", "GBP"); + cy.get("#bills-table") + .find("tbody tr") + .first() + .get("td") + .eq(4) + .should("have.text", " £6.13 "); + }); + + it("cost updates to 7.29 when EUR is selected in the currency drop down", () => { + // Act + cy.get("#currencies").click(); + cy.get("#EUR").click(); + + // Assert + cy.get("#selected-currency").should("have.text", "EUR"); + cy.get("#bills-table") + .find("tbody tr") + .first() + .get("td") + .eq(4) + .should("have.text", " €7.29 "); + }); + }); +}); diff --git a/ui/tests/e2e/tests/routes.spec.js b/ui/tests/e2e/tests/routes.spec.js index 6de6d3a..128baab 100644 --- a/ui/tests/e2e/tests/routes.spec.js +++ b/ui/tests/e2e/tests/routes.spec.js @@ -1,31 +1,39 @@ -describe('Route Tests', () => { - - before(() => { - cy.login('test@email.com', 'test1') - }) - - it('loads the my bills page', () => { - //Act - cy.visit('/my-bills') - - //Assert - cy.contains('h1', 'My Bills') - }) - - - it('bounces the root to the my bills page', () => { - //Act - cy.visit('/') - - //Assert - cy.contains('h1', 'My Bills') - }) - - it('loads the help page', () => { - //Act - cy.visit('/help') - - //Assert - cy.contains('h1', 'Frequently Asked Questions (FAQ)') - }) -}) \ No newline at end of file +describe("Bills Route Tests", () => { + before(() => { + cy.login("test@email.com", "test1"); + }); + + it("loads the my bills page", () => { + // Act + cy.visit("/my-bills"); + + // Assert + cy.contains("h1", "My Bills"); + }); + + it("bounces the root to the my bills page", () => { + // Act + cy.visit("/"); + + // Assert + cy.contains("h1", "My Bills"); + }); + + it("loads the help page", () => { + // Act + cy.visit("/help"); + + // Assert + cy.contains("h1", "Frequently Asked Questions (FAQ)"); + }); + + it("loads the all users page", () => { + // Act + cy.signOut(); + cy.adminLogin("operator@email.com", "test1"); + cy.visit("/view-users"); + + // Assert + cy.contains("h1", "View Users"); + }); +}); diff --git a/ui/tests/e2e/tests/viewusers.spec.js b/ui/tests/e2e/tests/viewusers.spec.js new file mode 100644 index 0000000..5bbebe8 --- /dev/null +++ b/ui/tests/e2e/tests/viewusers.spec.js @@ -0,0 +1,47 @@ +describe("My Users Tests", () => { + before(() => { + cy.adminLogin("operator@email.com", "test1"); + }); + + it("displays two rows in the users table", () => { + // Act + cy.visit("/view-users"); + + // Assert + cy.get("#users-table").find("tbody tr").should("have.length", 2); + }); + + it("Username filters the my users table", () => { + // Act + cy.get("#users-table").get("#username-filter").type("Username"); + + // Assert + cy.get("#users-table") + .find("tbody tr") + .should("have.text", "No users match the filter."); + }); + + it("Email filters the my users table", () => { + // Act + cy.get("#users-table").get("#email-filter").type("Email"); + + // Assert + cy.get("#users-table") + .find("tbody tr") + .should("have.text", "No users match the filter."); + }); + + it("Clicking pay bill redirects to the users bill page", () => { + // Act + cy.get("#users-table") + .get("#email-filter") + .focus() + .clear() + .type("test@email.com"); + cy.get("#users-table").get("#username-filter").focus().clear(); + cy.get("#viewUserBills").click(); + + // Assert + cy.get("h1").should("have.text", "Displaying bills for test_username"); + }); +});