diff --git a/frontend/cypress/integration/FR5.spec.js b/frontend/cypress/integration/FR5.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..4e185811d09f6e32c326b0a1794bbf3b857ec0ab --- /dev/null +++ b/frontend/cypress/integration/FR5.spec.js @@ -0,0 +1,62 @@ +var baseUrl = "localhost:9090" + +describe('Black box testing', () => { + function logWorkout(workoutname, publicbool){ + cy.get("#btn-create-workout").click(); + cy.get('input[name="name"]').type(workoutname); + if(publicbool){ + cy.get("#inputVisibility").select("Public"); + }else{ + cy.get("#inputVisibility").select("Private") + } + cy.get('input[name="date"]').click().then(input => { + input[0].dispatchEvent(new Event('input', { bubbles: true })) + input.val('2017-04-30T13:00') + }).click() + cy.get('#inputNotes').type('This is a note') + cy.get("#btn-ok-workout").click(); + } + + + it('Logg personal workout and check if added in my list', function() { + this.login(this.athleteUser) + cy.get('#list-my-workouts-list').click(); + cy.get('h5').contains('Public Workout'); + }) + + it('Logg public personal and check if added', function() { + this.login(this.athleteUser) + cy.get('#list-public-workouts-list').click(); + cy.get('h5').contains('Public Workout'); + }) + + it('Logg public and check if added', function() { + this.login(this.athleteUser) + logWorkout("Public Workout", true); + cy.url().should('include', "/workouts.html"); + cy.get('h5').contains('Public Workout') + }) + + + it('See details of public workout', function() { + this.login(this.athleteUser) + cy.get('#list-public-workouts-list').click(); + cy.get('h5').contains('Public Workout').parent().click(); + cy.get('#inputName').should('be.visible'); + cy.get('#inputNotes').should('be.visible'); + cy.get('#customFile').should('be.visible'); + }) + + it('User should not be able to see other private workouts', function() { + this.login(this.athleteUser) + logWorkout("Private Workout", false); + cy.get('#btn-logout', { timeout: 10000 }).click() + cy.wait(4000) + this.login(this.coachUser) + cy.wait(2000) + cy.get('h5').contains('Private Workout').should('not.exist'); + cy.get('#list-public-workouts-list').click(); + cy.get('h5').contains('Private Workout').should('not.exist'); + }) + +}) diff --git a/frontend/cypress/integration/exercise.spec.js b/frontend/cypress/integration/exercise.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..136247a409c30b8d5c62b8e38ac03e12e15f7b3b --- /dev/null +++ b/frontend/cypress/integration/exercise.spec.js @@ -0,0 +1,22 @@ +describe('Create exercise', () => { + it('Exercise creation', function() { + this.login(this.athleteUser) + cy.get('#nav-exercises').click() + cy.get('#btn-create-exercise').click() + cy.url().should('include', 'exercise.html') + + cy.get('#inputName', { timeout: 10000 }).type('Workout') + cy.get('#inputDescription').type('Description') + cy.get('#inputUnit').type('10') + cy.get('#inputDuration').type("-10") + cy.get('#inputCalories').type("-10") + cy.get('select[name="muscleGroup"]').eq(0).select('Legs', {force: true}) + + cy.intercept({method: 'POST', url: '/api/exercises/' }).as('createRequest') + cy.get('#btn-ok-exercise').click() + cy.wait('@createRequest') + + cy.get('.alert').should('be.visible'); + }) + +}) diff --git a/frontend/cypress/integration/first.spec.js b/frontend/cypress/integration/first.spec.js deleted file mode 100644 index 80d873078d5c1eed7bad1abc1f31b22ef05c79f6..0000000000000000000000000000000000000000 --- a/frontend/cypress/integration/first.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -describe('Create exercise', () => { - it('Exercise creation', function() { - this.login(this.athleteUser) - cy.get('#nav-exercises').click() - cy.get('#btn-create-exercise').click() - cy.url().should('include', 'exercise.html') -// - typeIn( - 'Workout', - 'Description', - '10', - '-10', - '-10', - 'Legs', - ) - cy.intercept({method: 'POST', url: '/api/exercises/' }).as('createRequest') - cy.get('#btn-ok-exercise').click() - cy.wait('@createRequest') - // Successfully created exercise - cy.url().should('include', 'exercises.html') - }) - - - function typeIn(name, description, unit, duration, calories, muscleGroup) { - cy.get('#inputName', { timeout: 10000 }).type(name) - cy.get('#inputDescription').type(description) - cy.get('#inputUnit').type(unit) - cy.get('#inputDuration').type(duration) - cy.get('#inputCalories').type(calories) - cy.get('select[name="muscleGroup"]').eq(0).select(muscleGroup, {force: true}) - } - -}) diff --git a/frontend/cypress/integration/goals.spec.js b/frontend/cypress/integration/goals.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..e3307c75d858e571ad2bff340d649bf934b28688 --- /dev/null +++ b/frontend/cypress/integration/goals.spec.js @@ -0,0 +1,73 @@ +const getDate = () => { + let d = new Date(); + const offset = d.getTimezoneOffset(); + d = new Date(d.getTime() - (offset*60*1000)); + return d.toISOString().split('T')[0]; +} + +// + +describe('Check goals', () => { + it('Create goal', function() { + this.login(this.athleteUser) + cy.get('#nav-goals').click() + cy.get('#btn-create-goal').click() + cy.url().should('include', 'goal.html') + + cy.get('#inputName', { timeout: 10000 }).type("GOAL_NAME") + cy.get('#inputDescription').type("GOAL_DESCRIPTION") + + cy.get('#inputDateTime') + .click() + .then(input => { + input[0].dispatchEvent(new Event('input', { bubbles: true })) + input.val('2017-04-30T13:00') + }) + .click() + // cy.intercept({method: 'POST', url: '/api/goal/' }).as('createRequest') + cy.get('#btn-ok-goal').click() + cy.wait(1000) + + cy.get('h2').eq(0).contains("GOAL_NAME") + //cy.wait('@createRequest') + cy.url().should('include', 'goals.html') + }) + + it('Edit goal', function() { + this.login(this.athleteUser) + cy.get('#nav-goals').click() + cy.get('.card-link') + .eq(0).click() + + cy.get('#inputName', { timeout: 10000 }).type("_EDITED") + + + + //cy.intercept({method: 'DELETE', url: '/api/goal/1/' }).as('createRequest') + cy.get('#btn-ok-goal').click() + cy.wait(1000) + + cy.get('h2').eq(0).contains("GOAL_NAME_EDITED") + + }) + + + it('Delete goal', function() { + this.login(this.athleteUser) + cy.get('#nav-goals').click() + cy.get('.card-link') + .eq(0).click() + + //cy.intercept({method: 'GET', url: '/api/goal/1/' }).as('createRequest') + //cy.wait('@createRequest') + cy.wait(1000) + + + //cy.intercept({method: 'DELETE', url: '/api/goal/1/' }).as('createRequest') + cy.get('#btn-delete-goal').click() + cy.wait(1000) + //cy.wait('@createRequest') + + cy.url().should('include', 'goals.html') + }) +}) diff --git a/frontend/cypress/integration/profile.spec.js b/frontend/cypress/integration/profile.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..761aad7d9aed86bd64fa84127e13bb47c80bef00 --- /dev/null +++ b/frontend/cypress/integration/profile.spec.js @@ -0,0 +1,35 @@ + + +describe('Test profile page', () => { + + it('Edit profile', function() { + this.login(this.athleteUser) + + cy.get('#nav-profile').click() + cy.get('#main_gym').type("SiT Moholt") + cy.get('#favourite_exercise').type("Cardio") + cy.get('#btn-edit-account').click() + cy.wait(1000) + cy.url().should('include', 'profile.html') + + cy.get('#main_gym').should('have.value', 'SiT Moholt'); + cy.get('#favourite_exercise').should('have.value', 'Cardio'); + }) + + + it('Connect to coach and see if the coach is added in profile', function() { + this.login(this.athleteUser) + + cy.get('#nav-mycoach').click() + cy.get('#input-coach').type(`${this.coachUser.username}`, {force: true}) + + cy.get('#button-edit-coach').click() + cy.get('#button-set-coach').click({force: true}) + cy.wait(2000) + + cy.get('#nav-profile').click() + cy.url().should('include', 'profile.html') + cy.get('#coach-content').contains(`${this.coachUser.username}`) + }) + +}) diff --git a/frontend/cypress/integration/register.spec.js b/frontend/cypress/integration/register.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..d7eddbc72e02273210eac1211caae5df8e94ef8d --- /dev/null +++ b/frontend/cypress/integration/register.spec.js @@ -0,0 +1,57 @@ + +const randomUsername = () => { + return Math.random().toString(36).substring(7); +} +var baseUrl = "localhost:9090" +/** + * The only validation done in the frontend is thorugh email + */ +const HundredAndFiftyTwo = "tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 tdt4242 "; + +describe('boundary tests registration page', () => { + beforeEach(() => { + cy.visit(`${baseUrl}/register.html`) + }); + + it('Test lower boundary limit', () => { + cy.get('#btn-create-account').click() + + cy.get('.alert').should('be.visible'); + cy.get('.alert').get('li').contains('username').children('ul').children('li').contains('This field may not be blank.') + cy.get('li').contains('password').children('ul').children('li').contains('This field may not be blank.') + cy.get('li').contains('password1').children('ul').children('li').contains('This field may not be blank.') + + }); + + it('Test upper boundary limit', () => { + + cy.get('input[name="username"]').type(HundredAndFiftyTwo) + cy.get('input[name="email"]').type(HundredAndFiftyTwo) + cy.get('input[name="password"]').type(HundredAndFiftyTwo) + cy.get('input[name="password1"]').type(HundredAndFiftyTwo) + cy.get('input[name="phone_number"]').type(HundredAndFiftyTwo) + cy.get('input[name="country"]').type(HundredAndFiftyTwo) + cy.get('input[name="city"]').type(HundredAndFiftyTwo) + cy.get('input[name="street_address"]').type(HundredAndFiftyTwo) + cy.get('input[name="main_gym"]').type(HundredAndFiftyTwo) + cy.get('input[name="favourite_exercise"]').type(HundredAndFiftyTwo) + + + cy.get('#btn-create-account').click() + cy.get('.alert').should('be.visible'); + cy.get('li').contains('Enter a valid username. This value may contain only letters, numbers, and @/./+/-/_ characters.') + cy.get('li').contains('Ensure this field has no more than 150 characters.') + cy.get('li').contains('Enter a valid email address.') + cy.get('li').contains('phone_number').children('ul').children('li').contains("Ensure this field has no more than 50 characters.") + cy.get('li').contains('country').children('ul').children('li').contains("Ensure this field has no more than 50 characters.") + cy.get('li').contains('city').children('ul').children('li').contains("Ensure this field has no more than 50 characters.") + cy.get('li').contains('street_address').children('ul').children('li').contains("Ensure this field has no more than 50 characters.") + cy.get('li').contains('main_gym').children('ul').children('li').contains("Ensure this field has no more than 50 characters.") + cy.get('li').contains('favourite_exercise').children('ul').children('li').contains("Ensure this field has no more than 50 characters.") + + }); + + + +}); + diff --git a/frontend/cypress/support/index.js b/frontend/cypress/support/index.js index e62e3c9aced19397650cf3b8c9733ee459cbe111..d63cbb61f5aefa07a13fc97a9819d486aa39d044 100644 --- a/frontend/cypress/support/index.js +++ b/frontend/cypress/support/index.js @@ -38,18 +38,21 @@ var athleteUser = { var apiUrl = "localhost:8000" var baseUrl = "localhost:9090" -function getRandomString(len=40) { - const dec2hex = dec => dec.toString(16).padStart(2, "0") - - var arr = new Uint8Array(len / 2) - window.crypto.getRandomValues(arr) - return Array.from(arr, dec2hex).join('') +export function makeid(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for ( var i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * + charactersLength)); + } + return result; } function generateUser() { return { - username: `test_user_${getRandomString(10)}`, - password: getRandomString(10), + username: `test_user_${makeid(10)}`, + password: makeid(10), } } diff --git a/frontend/www/goals.html b/frontend/www/goals.html index 5acb9e39511c0b52446837014a04fa7c9a18a116..b56e6085b8cc2705f1788cca5b24151daae80ce8 100644 --- a/frontend/www/goals.html +++ b/frontend/www/goals.html @@ -25,7 +25,7 @@ - <template id="template-exercise"> + <template id="template-goals"> <div class="card ml-1" style="width: 24rem;"> <div class="card-body"> <h2 class="card-title" ></h2> diff --git a/frontend/www/scripts/defaults.js b/frontend/www/scripts/defaults.js index f09e5b11770e94dd97921c59f0f18f6d5176d863..5adc962b90cfec8c01ec41e7846ad8a40ffa50fc 100644 --- a/frontend/www/scripts/defaults.js +++ b/frontend/www/scripts/defaults.js @@ -1 +1 @@ -const HOST = "http://localhost:8000"; +const HOST = "http://localhost:9090"; diff --git a/frontend/www/scripts/goal.js b/frontend/www/scripts/goal.js index 14afd3289c8ac038cc6a4ada76f8089e0a601c2a..bf3ec898afb4494a730248ec0067e61191270d73 100644 --- a/frontend/www/scripts/goal.js +++ b/frontend/www/scripts/goal.js @@ -33,6 +33,7 @@ async function createGoal() { async function deleteExercise(id) { let response = await sendRequest("DELETE", `${HOST}/api/goal/${id}/`); + console.log(`${HOST}/api/goal/${id}/`) if (!response.ok) { let data = await response.json(); let alert = createAlert(`Could not delete goal ${id}`, data); diff --git a/frontend/www/scripts/goals.js b/frontend/www/scripts/goals.js index a4b86cc19629535d37859e457532b6db47194b62..a01bfdbfc98b2267f77ecf05fdf0f741e0c06daa 100644 --- a/frontend/www/scripts/goals.js +++ b/frontend/www/scripts/goals.js @@ -6,7 +6,7 @@ async function fetchExerciseTypes(request) { let goals = data.results; let container = document.getElementById('div-content'); - let exerciseTemplate = document.querySelector("#template-exercise"); + let exerciseTemplate = document.querySelector("#template-goals"); goals.forEach(goal => { const exerciseAnchor = exerciseTemplate.content.firstElementChild.cloneNode(true); exerciseAnchor.href = `goal.html?id=${goal.id}`;