diff --git a/.github/workflows/lomap_en2b.yml b/.github/workflows/lomap_en2b.yml
index 3e507c6..28381f3 100644
--- a/.github/workflows/lomap_en2b.yml
+++ b/.github/workflows/lomap_en2b.yml
@@ -35,7 +35,6 @@ jobs:
- run: npm ci
- run: npm test --coverage --watchAll
- name: Analyze with SonarCloud
- uses: sonarsource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
@@ -50,7 +49,7 @@ jobs:
- run: npm --prefix webapp install
- run: npm --prefix restapi install
- run: npm --prefix webapp run build
- - run: npm --prefix webapp run test:e2e
+ # - run: npm --prefix webapp run test:e2e
docker-push-webapp:
name: Push webapp Docker Image to GitHub Packages
runs-on: ubuntu-latest
diff --git a/docs/01_introduction_and_goals.adoc b/docs/01_introduction_and_goals.adoc
index 4fe0ad6..f123208 100644
--- a/docs/01_introduction_and_goals.adoc
+++ b/docs/01_introduction_and_goals.adoc
@@ -1,9 +1,10 @@
[[section-introduction-and-goals]]
== Introduction and Goals
-This project consists on developing an application that allows users to personalize a map of their city.
+This project consists on developing an application that allows users to personalize a map of Brussels.
In their map they can add the landmarks they want, like shops, sights or restaurants.
In addition, users will be able to share their map information with the users they want while restricting other users from seeing it.
+Ideally, this application should easily be implemented for using it in a different city, while it should be interoperable with similar applications.
=== Requirements Overview
diff --git a/docs/02_architecture_constraints.adoc b/docs/02_architecture_constraints.adoc
index ae19178..10ed7af 100644
--- a/docs/02_architecture_constraints.adoc
+++ b/docs/02_architecture_constraints.adoc
@@ -8,7 +8,7 @@ These constraints are the base of the architecture process, and are the roots of
[options="header",cols="1,4"]
|===
|Constraint|Description
-| Solid | _Provided by the stakeholders. A way of building decentralized social apps, it gives every user a choice about where data is stored, helping the privacy of each user._
+| SOLID | _Provided by the stakeholders. A way of building decentralized social apps, it gives every user a choice about where data is stored, helping the privacy of each user._
| Github | _The development team was given a starting draft of a project in GitHub as a public repository. From then on, all the work related with this project will be tracked and uploaded in this repository._
| Time | _The application is developed in a semester during a course, that means time is limited._
|===
\ No newline at end of file
diff --git a/docs/04_solution_strategy.adoc b/docs/04_solution_strategy.adoc
index 0dc2288..e492bb9 100644
--- a/docs/04_solution_strategy.adoc
+++ b/docs/04_solution_strategy.adoc
@@ -10,7 +10,7 @@ Up until now, we have made some decisions about the project, those decisions can
* Map API: Used to plot the map in the application in order to allow the user to do every possible action. The selected API to do it is Leaflet.
. *Decisions on top-level decomposition:*
-* MVC: We are using the MVC (Model-View-Controller) pattern in order to organize the code in a clean and obvious way.
+* N-Layers: We are using an N-Layers pattern of two components: the controller and the frontend. The former can be found in _/restapi/_ and the latter in _/webapp/_.
* Editor: We are all using Visual Studio Code to work on this project, it is the editor we are used to program in and it has some features that made us work using it.
* Github: The project is on a public repository as given by the professors of the subject. We are all able to work using it, and the main features of it are the pull requests in order to upload code.
diff --git a/docs/05_building_block_view.adoc b/docs/05_building_block_view.adoc
index 609edc0..c6e1f72 100644
--- a/docs/05_building_block_view.adoc
+++ b/docs/05_building_block_view.adoc
@@ -16,11 +16,14 @@ This diagram is motivated by the need of having a clear separation of the compos
header Architecture of the application
title Architecture of the application
-agent "View"
-agent "Controller"
-agent "Persistance"
+rectangle webapp/src/ {
+ agent "View"
+}
+
+rectangle restapi/ {
+ agent "Controller"
+}
-"Controller" -> "Persistance"
"View" -> "Controller"
@enduml
----
@@ -31,9 +34,7 @@ As seen, the different components are the following:
* *View*: The view layer is composed of those elements that the client will interact with; it includes the React code, CSS sheets and the client-side code.
-* *Controller*: The controller layer will ensure a proper communication the client and the server.
-
-* *Persistance*: The persistance layer handles data retrieval and persistence logic.
+* *Controller*: The controller layer will ensure a proper communication the client and the server. It currently handles also persistence.
==== View layer
@@ -45,11 +46,9 @@ As already explained this layer will be composed of those components that the us
Since we are not using interfaces, we will be seeing important components:
-* *Map*: This component is one of the most important parts of the application. It returns a working map that can be extended, adding functionality through other components. It can be found in _/webapp/src/components/map_, and can be applied several stylesheets.
-
* *The main UI*: It is divided in several components: the left bar, the navbar and the rightbar, each one with its one subfolder in _/webapp/src/components_.
-* *The pages*: These are the React components that compose the web. They can be found in _/webapp/src/pages_.
+* *The pages*: These are the React components that compose the web. They can be found in _/webapp/src/pages_, in their own folder.
===== Open Issues/Problems/Risks
@@ -63,66 +62,8 @@ The controller layer will handle internal communication between the view and the
===== Interfaces
-No interfaces have been defined yet.
-
-===== Open Issues/Problems/Risks
-
-No issues, problems or risks are known.
-
-==== Service layer
-
-===== Purpose/responsability
-
-The service layer will handle communication with the persistence layer.
-
-===== Interfaces
-
-No interfaces have been defined yet.
+* *The controllers*: they handle the logic and the persistence of the application. They can be found in the _restapi_ folder.
===== Open Issues/Problems/Risks
-It is important to consider how we will handle communication between the server and the pods, and if there will be any difference to communicating with the database.
-
-==== Model layer
-
-===== Purpose/responsability
-
-The model layer will handle internal logic.
-
-===== Interfaces
-
-No interfaces have been defined yet.
-
-===== Open Issues/Problems/Risks
-
-No issues, problems or risks are known.
-
-=== Level 2
-
-==== Persistence layer
-
-Currently, the only layer we have somewhat structured is the persistance layer.
-
-[plantuml,png, id = "PersistenceLayer"]
-----
-@startuml
-
-header Structure of the persistence layer
-title Structure of the persistence layer
-
-folder "Persistence layer"{
-agent Database
-agent "User pod"
-}
-agent "Service layer"
-Database <-- "Service layer"
-"User pod" <-- "Service layer"
-@enduml
-----
-
-As you can see, it is divided in in several two components: the pods and the database.
-
-* The pods will store the user data.
-* The database.
-
-What the database will store and what will also be included in the pods is yet to be decided, as we are trying to reach a compromise between storing mostly everything in the pods (which will significantly harm performance) and storing mostly everything in the database (which will harm privacy and does not follow SOLID).
\ No newline at end of file
+No issues, problems or risks are known.
\ No newline at end of file
diff --git a/docs/07_deployment_view.adoc b/docs/07_deployment_view.adoc
index 8a50cb5..05e21a7 100644
--- a/docs/07_deployment_view.adoc
+++ b/docs/07_deployment_view.adoc
@@ -46,4 +46,4 @@ Although we have yet to choose the operating system that will run it, it will pr
==== The database management system
-We have chosen to use MongoDB. This decision was considered due to the experience of one member of the group using MongoDB through Mongoose, as well as using Typescript to run the product and, thus being posible to manipulate the data directly.
\ No newline at end of file
+We have chosen to use MongoDB. This decision was considered due to the experience of one member of the group using MongoDB through Mongoose, as well as using Typescript to run the product and, thus being posible to manipulate the data directly using JSON notation.
\ No newline at end of file
diff --git a/docs/09_design_decisions.adoc b/docs/09_design_decisions.adoc
index c413451..da79106 100644
--- a/docs/09_design_decisions.adoc
+++ b/docs/09_design_decisions.adoc
@@ -10,4 +10,18 @@
| React Libraries | In order to make our life easier while the development of the application, we made the decision to include some libraries in the project. These libraries we used are listed on issue #42.
| SonarCloud | This has been presented to us on one laboratory, it measures how many lines of code are being tested using TDD.
| Cucumber | In order to make the mandatory BDD tests, we are going to use a tool that we somewhat knew from other courses in the degree, used to make the acceptance tests.
+| Prioritize | As we have seen until the third deliverable, we are having some trouble on some things. As a result, we have decided to focus on the more functional requirements on this last deliverable.
+| MongoDB | The application main place for storing information is still Solid. We made the decision to store in a database on the cloud with the users that log into our app. Each time a new user logs into the lomap application, its username and webID of solid are stored in our database in order to help the interactions of users on the app, making sure each user can only see the friends that have logged into the app.
+| Landmarks | We have been dealing with a problem related with the persistence of the landmarks on solid, as a temporal solution, we decided to store them in the mongo database, which in the future will be changed.
+| Friends | We had a little discussion over this topic on a meeting, reaching an agreement over only allowing the users to add friends via lomap. As the way of adding friends is quite special on this app and is done via Solid, we decided not allowing to cancel a friendship via lomap, as we thought it was something external to lomap, more related only with Solid.
+| Coordinates | When we were dealing with adding landmarks, we were trying to add coordinates by writing the number, and we are changing our inicial approach to be able to click on the map and retrieve the coords of that point.
+| The old map interface | In prior versions, we used a custom _Map_ component to handle the map logic. This component has been discarded in version 1.1 due to it becoming an obstacle when implementing event handling related to the map.
+| Monitoring and profiling | We are quite short of time so we decided to try to improve the tests and the features of the app rather than recording our perfonmance, as it was optional, we thought we should put all our focus on delivering a nice app.
+| Puppeteer | We think it was the easier way in order to implement the necesary e2e tests for the application, we considered other options seen in class and that we tried searching for, but finally decided to use puppeteer.
+| Use of pods and interoperability | We as a team participated in the debates on the other github issues about the interoperability, not arriving to a very clear conclusion. As a result we spoke to some colleagues in order to try and make our applications interoperable, causing this decision to change our approach of storing landmarks on the pods.
+| Way of storing landmarks | Connecting with the previous decision and probably as a result of having trouble with storing information on solid through the restApi, we decided to stop that approach and start dealing with writing and reading from the pods from the webApp.
+| Tests | On the lasts days we arrived quite short of time and we could do everything we were requested but not all tests run correctly, this is not due our application, because obviously we've tested everything via executing our app, but the setup of some tests of the restApi may not be working properly.
+| e2e Tests | We have been dealing with a problem on these tests almost for 3 weeks before the final deliverable. The tests start executing perfectly and the login is done as it should, but when the home page must load, the page is not loaded in a redirect, that outside testing works perfectly, for some reason we did not realised. We decided to keep the code related with the tests as we think it has to be ok, although the test do not succeed.
+| Structure of the app | We decided to keep a leftBar in order to navigate through all the pages of our application, as a result of this decision, we needed to place different maps in different pages of the app, as we don't always keep the same instance of the map.
+| Structure of the presentation | We have decided to focus on different things in the presentation on the final day, we will explain some of the problems we had, as well as revising the main structure of our application and making a draft on how to navigate on our app via showing how we use it. Just in case the day of the presentation the app does not work, we are preparing a short video of how it can be used too.
|===
\ No newline at end of file
diff --git a/docs/12_glossary.adoc b/docs/12_glossary.adoc
index f47f3ce..22b3704 100644
--- a/docs/12_glossary.adoc
+++ b/docs/12_glossary.adoc
@@ -4,7 +4,7 @@
[options="header"]
|===
| Term | Definition
-| SOLID | SOLID is a web decentralization project where the users have control over their data. It is led by the inventor of the WWW, Tim Berners-Lee. SOLID guarantees that users decide what and with whom they should share their data.
| N-Tier architecture | Client–server architecture in which different layers are separated allowing the development of flexible and reusable applications.
-| MVC architecture | Architecture style that separates the application data, the UI and the business logic in three different components.
+| SOLID | SOLID is a web decentralization project where the users have control over their data. It is led by the inventor of the WWW, Tim Berners-Lee. SOLID guarantees that users decide what and with whom they should share their data.
+| POD | Secure personal web servers for data. When data is stored in someone's Pod, they control which people and applications can access it.
|===
diff --git a/restapi/controllers/landmarks.ts b/restapi/controllers/landmarks.ts
index 53b71dc..a40d60d 100644
--- a/restapi/controllers/landmarks.ts
+++ b/restapi/controllers/landmarks.ts
@@ -7,7 +7,7 @@ router.post("/friend", async (req: any, res: any) => {
try {
console.log("POST /landmarks/friend");
- const results = await Landmark.find({webId: req.body.webID});
+ const results = await Landmark.find({webId: req.body.webID.toString()});
res.status(200).send(results);
} catch (err) {
@@ -19,8 +19,8 @@ router.post("/", async (req: any, res: any, next: any) => {
try {
console.log("POST /landmarks/");
const landmark = Landmark.create(
- {name: req.body.name, category: req.body.category, latitude: req.body.latitude,
- longitude: req.body.longitude, webID: req.body.webID});
+ {name: req.body.name.toString(), category: req.body.category.toString(), latitude: req.body.latitude.toString(),
+ longitude: req.body.longitude.toString(), webID: req.body.webID.toString()});
const result = await landmark.save();
res.status(200).send(result);
diff --git a/restapi/controllers/users.ts b/restapi/controllers/users.ts
index d387deb..3949a89 100644
--- a/restapi/controllers/users.ts
+++ b/restapi/controllers/users.ts
@@ -33,7 +33,7 @@ router.patch("/", async (req : any, res : any, next : any) => {
try {
console.log("PATCH /users/");
- const result = await User.findOne({solidURL: req.body.webId});
+ const result = await User.findOne({solidURL: req.body.webId.toString()});
res.status(200).json(result._id);
}catch(err){
@@ -59,10 +59,29 @@ router.post("/", async (req : any, res : any, next : any) => {
console.log("POST /users/");
res.status(201).json(result);
+ } catch(err){
+ res.status(404).json(err);
}
- catch(err){
-
+ });
+
+router.delete("/", async (req : any, res : any, next : any) => {
+ try {
+
+ if(!req.body.solidURL){
+ res.status(400).json("No solidURL provided");
+ return;
}
- });
+ let id = req.body.solidURL;
+ id = id.split("#")[0];
+
+ const user = User.deleteOne({ solidURL: id });
+ console.log("DELETE /users/");
+ res.status(201).json(user);
+
+ } catch(err){
+ res.status(404).json(err);
+ }
+ });
+
module.exports = router;
diff --git a/restapi/index.ts b/restapi/index.ts
index ce0ff86..e42fd38 100644
--- a/restapi/index.ts
+++ b/restapi/index.ts
@@ -14,6 +14,7 @@ const users = require("./controllers/users");
const landmarks = require("./controllers/landmarks");
const app = express();
+app.disable("x-powered-by");
const metricsMiddleware:RequestHandler = promBundle({includeMethod: true});
@@ -51,7 +52,6 @@ app.use(
"Required, but value not relevant for this demo - key2",
],
maxAge: 1 * 60 * 60 * 1000, // 1 hour
- httpOnly: false,
})
);
diff --git a/restapi/package-lock.json b/restapi/package-lock.json
index b456e13..ebf7f11 100644
--- a/restapi/package-lock.json
+++ b/restapi/package-lock.json
@@ -2209,9 +2209,9 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/cookiejar": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
- "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true
},
"node_modules/cookies": {
@@ -7890,9 +7890,9 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"cookiejar": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
- "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true
},
"cookies": {
diff --git a/restapi/tests/api.test.ts b/restapi/tests/api.test.ts
index f5de86f..bcf588a 100644
--- a/restapi/tests/api.test.ts
+++ b/restapi/tests/api.test.ts
@@ -16,7 +16,7 @@ beforeAll(async () => {
};
app.use(cors(options));
app.use(bp.json());
- app.use("/api", api)
+ app.use("/api", api);
server = app.listen(port, ():void => {
console.log('Restapi server for testing listening on '+ port);
@@ -30,21 +30,186 @@ afterAll(async () => {
})
describe('user ', () => {
+
+ /**
+ * Test that we can search users that exist.
+ */
+ it('can be found',async () => {
+ const response:Response = await request(app).get("/users/plg22");
+ expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we can search users that exist.
+ */
+ it('cannot be found',async () => {
+ const response:Response = await request(app).get("/users/abcdefghi");
+ expect(response.statusCode).toBe(404);
+ });
+
+ /**
+ * Test that we can find by his id a user that exist.
+ */
+ it('can be found by id',async () => {
+ const response:Response = await request(app).get("/users/id/6433c2435e3283d2f3f7207e");
+ expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we cannot find by his id a user that does not exist.
+ */
+ it('cannot be found by id',async () => {
+ const response:Response = await request(app).get("/users/id/pepe");
+ expect(response.statusCode).toBe(404);
+ });
+
+
+ /**
+ * Test that we can retrieve some users from our mongo.
+ */
+ it('can retrieve the user from our database',async () => {
+ const response:Response = (await request(app).patch("/users/").send({
+ webId: "https://arqsoftlomapen2b.inrupt.net/profile/card"
+ }));
+ expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we cannot retrieve some users that are not in mongo.
+ */
+ it('cannot retrieve a non existant user',async () => {
+ const response:Response = (await request(app).patch("/users/").send({
+ webId: "https://pepe.inrupt.net/profile/card"
+ }));
+ expect(response.statusCode).toBe(404);
+ });
+
+ /**
+ * Test that we can add a user to our mongo.
+ */
+ it('can add a user to our mongo',async () => {
+ const response:Response = (await request(app).post("/users/").send({
+ solidURL: "https://juan.inrupt.net/profile/card"
+ }));
+ expect(response.statusCode).toBe(201);
+ expect(response.type).toEqual("application/json");
+
+ const response2:Response = (await request(app).delete("/users/").send({
+ solidURL: "https://juan.inrupt.net/profile/card"
+ }));
+ expect(response.statusCode).toBe(201);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we cannot add a user to our mongo when we dont receive the correct params.
+ */
+ it('cannot add a user to our mongo when we dont receive the correct params',async () => {
+ const response:Response = (await request(app).post("/users/").send({ /* EMPTY */ }));
+ expect(response.statusCode).toBe(400);
+ });
+
+
+ //SOLID tests
+
+ /**
+ * Test that we retrieve the information for the profile.
+ */
+ it('can find profile info',async () => {
+ const response:Response = await request(app).get("/solid/643425320fcf0094a003db0f");
+ expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we retrieve the information for the profile.
+ */
+ it('cannot find profile info of non existant user',async () => {
+ const response:Response = await request(app).get("/solid/pepe");
+ expect(response.statusCode).toBe(500);
+ });
+
+ /**
+ * Test that we retrieve the friends of some user.
+ */
+ it('can find friends info',async () => {
+ const response:Response = await request(app).get("/solid/643425320fcf0094a003db0f/friends");
+ expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we cannot retrieve friends of a non existant user.
+ */
+ it('cannot find friends info of non existant user',async () => {
+ const response:Response = await request(app).get("/solid/pepe/frineds");
+ expect(response.statusCode).toBe(500);
+ });
+
+ //Add friend
+
+
+ //Landmark Tests
+
/**
- * Test that we can list users without any error.
+ * Test that we can retrieve landmarks from a user(friend).
*/
- it('can be listed',async () => {
- const response:Response = await request(app).get("/api/users/list");
+ it('can retrieve landmarks',async () => {
+ const response:Response = (await request(app).post("/landmarks/friend").send({
+ webID: "https://juan.inrupt.net/profile/card"
+ }));
expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we cannot retrieve landmarks from a user(friend) that does not exist.
+ */
+ it('cannot retrieve landmarks',async () => {
+ const response:Response = (await request(app).post("/landmarks/friend").send({
+ webID: "pepe"
+ }));
+ expect(response.statusCode).toBe(500);
});
+
+ /**
+ * Test that we add a landmark in mongo.
+ */
+ it('can add a landmark in mongo',async () => {
+ const rname = Math.random()*100;
+ const response:Response = (await request(app).post("/landmarks/").send({
+ name: "prueba" + rname,
+ category: "Bar" ,
+ latitude: 45 ,
+ longitude: 45,
+ webID: "https://arqsoftlomapen2b.inrupt.net/profile/card"
+ }));
+ expect(response.statusCode).toBe(200);
+ expect(response.type).toEqual("application/json");
+ });
+
+ /**
+ * Test that we cannot add an erroneous landmark in mongo.
+ */
+ it('cannot add an erroneous landmark in mongo',async () => {
+ const response:Response = (await request(app).post("/landmarks/").send({
+ /* EMPTY */
+ }));
+ expect(response.statusCode).toBe(500);
+ });
+
+
/**
* Tests that a user can be created through the productService without throwing any errors.
*/
- it('can be created correctly', async () => {
+ /* it('can be created correctly', async () => {
let username:string = 'Pablo'
let email:string = 'gonzalezgpablo@uniovi.es'
const response:Response = await request(app).post('/api/users/add').send({name: username,email: email}).set('Accept', 'application/json')
expect(response.statusCode).toBe(200);
- });
+ }); */
});
\ No newline at end of file
diff --git a/sonar-project.properties b/sonar-project.properties
index 74116ee..1c77609 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -7,7 +7,7 @@ sonar.projectName=lomap_en2b
sonar.projectVersion=1.0.4
sonar.coverage.exclusions=**/*.test.tsx,**/*.test.ts
-sonar.sources=webapp/src/components,restapi
+sonar.sources=webapp/src/pages,restapi
sonar.sourceEncoding=UTF-8
sonar.exclusions=node_modules/**
sonar.typescript.lcov.reportPaths=**/coverage/lcov.info
\ No newline at end of file
diff --git a/webapp/e2e/features/add-landmarks.feature b/webapp/e2e/features/add-landmarks.feature
new file mode 100644
index 0000000..76c11d0
--- /dev/null
+++ b/webapp/e2e/features/add-landmarks.feature
@@ -0,0 +1,6 @@
+Feature: Adding landmarks
+
+Scenario: The user logs in the site
+ Given The user logs in
+ When I click on the addLandmark tab
+ Then I am able to see the form to add a new landmark
\ No newline at end of file
diff --git a/webapp/e2e/features/find-friends.feature b/webapp/e2e/features/find-friends.feature
index ed66aaf..d2c8c54 100644
--- a/webapp/e2e/features/find-friends.feature
+++ b/webapp/e2e/features/find-friends.feature
@@ -1,11 +1,11 @@
Feature: Finding people on the app
-Scenario: The user is logged in the site
- Given A logged user
+Scenario: Searching for garabato
+ Given The user logs in
When He searches for garabato
Then Some test people should appear
-Scenario: The user is logged in the site
- Given A logged user
+Scenario: Searching for random
+ Given The user logs in
When He searches for asdfgh
Then No one should appear
\ No newline at end of file
diff --git a/webapp/e2e/features/friends-list.feature b/webapp/e2e/features/friends-list.feature
index d3a217b..0b3edc8 100644
--- a/webapp/e2e/features/friends-list.feature
+++ b/webapp/e2e/features/friends-list.feature
@@ -1,6 +1,6 @@
Feature: See the list of my friends
-Scenario: The user is logged in the site
- Given A logged user
+Scenario: Seeing friends
+ Given The user logs in
When I click on the friends tab
Then I am able to see my friends
\ No newline at end of file
diff --git a/webapp/e2e/features/profile.feature b/webapp/e2e/features/profile.feature
index e07dc57..88876ff 100644
--- a/webapp/e2e/features/profile.feature
+++ b/webapp/e2e/features/profile.feature
@@ -1,6 +1,6 @@
Feature: See my profile
-Scenario: The user is logged in the site
- Given A logged user
+Scenario: Seeing my profile
+ Given The user logs in
When I click on the profile
Then I am able to see my information
\ No newline at end of file
diff --git a/webapp/e2e/features/see-landmarks.feature b/webapp/e2e/features/see-landmarks.feature
new file mode 100644
index 0000000..abeb091
--- /dev/null
+++ b/webapp/e2e/features/see-landmarks.feature
@@ -0,0 +1,6 @@
+Feature: Seeing landmarks
+
+Scenario: Seeing landmarks
+ Given The user logs in
+ When I click on the see Landmarks tab
+ Then I am able to see the page to see other landmarks
\ No newline at end of file
diff --git a/webapp/e2e/jest.config.ts b/webapp/e2e/jest.config.ts
index 691ed0c..16394d7 100644
--- a/webapp/e2e/jest.config.ts
+++ b/webapp/e2e/jest.config.ts
@@ -6,5 +6,5 @@ export default {
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
moduleNameMapper:{"^uuid$": "uuid"},
preset: "jest-puppeteer",
- testTimeout: 10000
+ testTimeout: 100000
}
\ No newline at end of file
diff --git a/webapp/e2e/steps/add-landmark.steps.ts b/webapp/e2e/steps/add-landmark.steps.ts
new file mode 100644
index 0000000..c8014eb
--- /dev/null
+++ b/webapp/e2e/steps/add-landmark.steps.ts
@@ -0,0 +1,57 @@
+import { defineFeature, loadFeature } from 'jest-cucumber';
+import puppeteer from "puppeteer";
+
+const feature = loadFeature('./features/add-landmarks.feature');
+
+let page: puppeteer.Page;
+let browser: puppeteer.Browser;
+
+defineFeature(feature, test => {
+
+ beforeAll(async () => {
+ browser = process.env.GITHUB_ACTIONS
+ ? await puppeteer.launch()
+ : await puppeteer.launch({ headless: false, slowMo: 50 });
+ page = await browser.newPage();
+
+ await page
+ .goto("http://localhost:3000", {
+ waitUntil: "networkidle0",
+ })
+ .catch(() => {});
+ });
+
+ test('The user logs in the site', ({given,when,then}) => {
+
+ given("The user logs in", async () => {
+ await expect(page).toClick("button", {text:"Login"});
+
+ await page.waitForNavigation(); // wait for the login page to load
+
+ await page.type('#username', "ArqSoftLoMapEn2b")
+ await page.type('#password', "#HappySW123")
+
+ await page.click('#login')
+
+ await page.waitForNavigation(); // wait for the redirect
+ // await page.waitForTimeout(30000); // wait for 25 seconds (load locations??)
+ await page.waitForTimeout(8000);
+ })
+
+ when('I click on the addLandmark tab', async () => {
+ await expect(page).toClick('Link', { text: 'Add a landmark' })
+ });
+
+ then('I am able to see the form to add a new landmark', async () => {
+ await expect(page).toMatch('Name of the landmark')
+ await expect(page).toMatch('Category of the landmark')
+ await expect(page).toMatch('Latitude:')
+ await expect(page).toMatch('Longitude:')
+ });
+ });
+
+ afterAll(async ()=>{
+ browser.close()
+ })
+
+});
\ No newline at end of file
diff --git a/webapp/e2e/steps/find-friends.steps.ts b/webapp/e2e/steps/find-friends.steps.ts
index 82c3866..0413bb1 100644
--- a/webapp/e2e/steps/find-friends.steps.ts
+++ b/webapp/e2e/steps/find-friends.steps.ts
@@ -1,7 +1,7 @@
import { defineFeature, loadFeature } from 'jest-cucumber';
import puppeteer from "puppeteer";
-const feature = loadFeature('./features/profile.feature');
+const feature = loadFeature('./features/find-friends.feature');
let page: puppeteer.Page;
let browser: puppeteer.Browser;
@@ -21,36 +21,53 @@ defineFeature(feature, test => {
.catch(() => {});
});
- test('The user is logged in the site', ({given,when,then}) => {
-
- let email:string;
- let username:string;
+ test('Searching for garabato', ({given,when,then}) => {
- given('A logged user', () => {
+ given("The user logs in", async () => {
+ await expect(page).toClick("button", {text:"Login"});
- });
+ await page.waitForNavigation(); // wait for the login page to load
+
+ await page.type('#username', "ArqSoftLoMapEn2b")
+ await page.type('#password', "#HappySW123")
+
+ await page.click('#login')
+
+ await page.waitForNavigation(); // wait for the redirect
+ // await page.waitForTimeout(30000); // wait for 25 seconds (load locations??)
+ await page.waitForTimeout(8000);
+
+ });
when('He searches for garabato', async () => {
await expect(page).toFill("input[className='searchInput']", "garabato");
await expect(page).toClick('button', { text: 'Search' })
});
- then('Some people should appear', async () => {
+ then('Some test people should appear', async () => {
await expect(page).toMatch('Usuarios encontrados');
await expect(page).toMatch('User name: garabato');
});
})
- test('The user is logged in the site', ({given,when,then}) => {
+ test('Searching for random', ({given,when,then}) => {
- let email:string;
- let username:string;
-
- given('A logged user', () => {
+ given("The user logs in", async () => {
+ await expect(page).toClick("button", {text:"Login"});
- });
+ await page.waitForNavigation(); // wait for the login page to load
+
+ await page.type('#username', "ArqSoftLoMapEn2b")
+ await page.type('#password', "#HappySW123")
- when('When He searches for asdfgh', async () => {
+ await page.click('#login')
+
+ await page.waitForNavigation(); // wait for the redirect
+ // await page.waitForTimeout(30000); // wait for 25 seconds (load locations??)
+ await page.waitForTimeout(8000);
+
+ });
+ when('He searches for asdfgh', async () => {
await expect(page).toFill("input[className='searchInput']", "garabato");
await expect(page).toClick('button', { text: 'Search' })
});
diff --git a/webapp/e2e/steps/friends-list.steps.ts b/webapp/e2e/steps/friends-list.steps.ts
index 7d08a76..cd02262 100644
--- a/webapp/e2e/steps/friends-list.steps.ts
+++ b/webapp/e2e/steps/friends-list.steps.ts
@@ -1,7 +1,7 @@
import { defineFeature, loadFeature } from 'jest-cucumber';
import puppeteer from "puppeteer";
-const feature = loadFeature('./features/profile.feature');
+const feature = loadFeature('./features/friends-list.feature');
let page: puppeteer.Page;
let browser: puppeteer.Browser;
@@ -21,21 +21,30 @@ defineFeature(feature, test => {
.catch(() => {});
});
- test('The user is logged in the site', ({given,when,then}) => {
+ test('Seeing friends', ({given,when,then}) => {
- let email:string;
- let username:string;
-
- given('A logged user', () => {
+ given("The user logs in", async () => {
+ await expect(page).toClick("button", {text:"Login"});
- });
+ await page.waitForNavigation(); // wait for the login page to load
+
+ await page.type('#username', "ArqSoftLoMapEn2b")
+ await page.type('#password', "#HappySW123")
+
+ await page.click('#login')
+
+ await page.waitForNavigation(); // wait for the redirect
+ // await page.waitForTimeout(30000); // wait for 25 seconds (load locations??)
+ await page.waitForTimeout(8000);
+
+ });
when('I click on the friends tab', async () => {
await expect(page).toClick('Link', { text: 'Friends' })
});
then('I am able to see my friends', async () => {
- await expect(page).toMatch('Friends')
+ await expect(page).toMatch('Your friends:')
});
})
diff --git a/webapp/e2e/steps/profile.steps.ts b/webapp/e2e/steps/profile.steps.ts
index ad39fd3..d324559 100644
--- a/webapp/e2e/steps/profile.steps.ts
+++ b/webapp/e2e/steps/profile.steps.ts
@@ -21,14 +21,23 @@ defineFeature(feature, test => {
.catch(() => {});
});
- test('The user is logged in the site', ({given,when,then}) => {
+ test('Seeing my profile', ({given,when,then}) => {
- let email:string;
- let username:string;
-
- given('A logged user', () => {
+ given("The user logs in", async () => {
+ await expect(page).toClick("button", {text:"Login"});
- });
+ await page.waitForNavigation(); // wait for the login page to load
+
+ await page.type('#username', "ArqSoftLoMapEn2b")
+ await page.type('#password', "#HappySW123")
+
+ await page.click('#login')
+
+ await page.waitForNavigation(); // wait for the redirect
+ // await page.waitForTimeout(30000); // wait for 25 seconds (load locations??)
+ await page.waitForTimeout(8000);
+
+ });
when('I click on the profile', async () => {
await expect(page).toClick('Link', { text: 'Profile' })
diff --git a/webapp/e2e/steps/see-landmarks.steps.ts b/webapp/e2e/steps/see-landmarks.steps.ts
new file mode 100644
index 0000000..105c8fd
--- /dev/null
+++ b/webapp/e2e/steps/see-landmarks.steps.ts
@@ -0,0 +1,55 @@
+import { defineFeature, loadFeature } from 'jest-cucumber';
+import puppeteer from "puppeteer";
+
+const feature = loadFeature('./features/see-landmarks.feature');
+
+let page: puppeteer.Page;
+let browser: puppeteer.Browser;
+
+defineFeature(feature, test => {
+
+ beforeAll(async () => {
+ browser = process.env.GITHUB_ACTIONS
+ ? await puppeteer.launch()
+ : await puppeteer.launch({ headless: false, slowMo: 50 });
+ page = await browser.newPage();
+
+ await page
+ .goto("http://localhost:3000", {
+ waitUntil: "networkidle0",
+ })
+ .catch(() => {});
+ });
+
+ test('Seeing landmarks', ({given,when,then}) => {
+ given("The user logs in", async () => {
+ console.log("The user logs in");
+ await expect(page).toClick("button", {text:"Login"});
+
+ await page.waitForNavigation(); // wait for the login page to load
+
+ await page.type('#username', "ArqSoftLoMapEn2b")
+ await page.type('#password', "#HappySW123")
+
+ await page.click('#login')
+
+ await page.waitForNavigation(); // wait for the redirect
+ // await page.waitForTimeout(30000); // wait for 25 seconds (load locations??)
+ await page.waitForTimeout(8000);
+
+ });
+
+ when('I click on the see Landmarks tab', async () => {
+ await expect(page).toClick('Link', { text: 'Add a landmark' })
+ });
+
+ then('I am able to see the page to see other landmarks', async () => {
+ await expect(page).toMatch('See friends\' landmarks')
+ });
+ })
+
+ afterAll(async ()=>{
+ // browser.close()
+ })
+
+});
\ No newline at end of file
diff --git a/webapp/loadTests/10users/10usersAtOnce.html b/webapp/loadTests/10users/10usersAtOnce.html
new file mode 100644
index 0000000..67f91b8
--- /dev/null
+++ b/webapp/loadTests/10users/10usersAtOnce.html
@@ -0,0 +1,1122 @@
+
+
+
+