Commit 5a371ef9 authored by Pernille Nødtvedt Welle-Watne's avatar Pernille Nødtvedt Welle-Watne
Browse files

Merge branch 'e2e' into 'master'

E2e

See merge request !7
parents 3f738b25 3d6e6952
Pipeline #115484 failed with stages
in 45 seconds
......@@ -126,3 +126,29 @@ If you want to run this as a mobile application
It's possible you will need to add the platforms you want to run and build.
The following documentation can be used to run the application in an Android emulator: \
https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html
##Tests
### Django
To run test for backend enter
`python manage.py test`
With coverage:
`coverage run manage.py test`
`coverage report -m ./users/serializers.py ./workouts/permissions.py`
### Cypress
To run the test in cypress go to the frontend folder and enter in different terminals:
`npm run test:dev`
`npm run django:testserver`
`npm run cypress:open`
# Generated by Django 3.1 on 2021-03-04 22:41
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('comments', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='comment',
name='timestamp',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='like',
name='timestamp',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]
# Generated by Django 3.1 on 2021-03-04 22:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('suggested_workouts', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='suggestedworkout',
name='visibility',
),
migrations.AddField(
model_name='suggestedworkout',
name='status',
field=models.CharField(choices=[('a', 'Accepted'), ('p', 'Pending'), ('d', 'Declined')], default='p', max_length=8),
),
migrations.AlterField(
model_name='suggestedworkout',
name='coach',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 3.1 on 2021-03-04 22:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('suggested_workouts', '0002_auto_20210304_2241'),
]
operations = [
migrations.AddField(
model_name='suggestedworkout',
name='visibility',
field=models.CharField(default='PU', max_length=8),
),
]
# Generated by Django 3.1 on 2021-03-04 23:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('suggested_workouts', '0003_suggestedworkout_visibility'),
]
operations = [
migrations.RemoveField(
model_name='suggestedworkout',
name='visibility',
),
]
# Generated by Django 3.1 on 2021-03-04 23:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('suggested_workouts', '0004_remove_suggestedworkout_visibility'),
]
operations = [
migrations.AddField(
model_name='suggestedworkout',
name='visibility',
field=models.CharField(blank=True, default='', max_length=8, null=True),
),
]
# Generated by Django 3.1 on 2021-03-05 09:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('suggested_workouts', '0005_suggestedworkout_visibility'),
]
operations = [
migrations.RemoveField(
model_name='suggestedworkout',
name='visibility',
),
migrations.DeleteModel(
name='WorkoutRequest',
),
]
# Generated by Django 3.1 on 2021-03-04 22:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import users.models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='AthleteFile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to=users.models.athlete_directory_path)),
],
),
migrations.RemoveField(
model_name='offer',
name='offer_type',
),
migrations.AddField(
model_name='offer',
name='status',
field=models.CharField(choices=[('a', 'Accepted'), ('p', 'Pending'), ('d', 'Declined')], default='p', max_length=8),
),
migrations.AddField(
model_name='offer',
name='timestamp',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='user',
name='city',
field=models.TextField(blank=True, max_length=50),
),
migrations.AddField(
model_name='user',
name='country',
field=models.TextField(blank=True, max_length=50),
),
migrations.AddField(
model_name='user',
name='phone_number',
field=models.TextField(blank=True, max_length=50),
),
migrations.AddField(
model_name='user',
name='street_address',
field=models.TextField(blank=True, max_length=50),
),
migrations.AlterField(
model_name='offer',
name='recipient',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='received_offers', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='user',
name='coach',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='athletes', to=settings.AUTH_USER_MODEL),
),
migrations.DeleteModel(
name='OfferResponse',
),
migrations.AddField(
model_name='athletefile',
name='athlete',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='coach_files', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='athletefile',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='athlete_files', to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 3.1 on 2021-03-04 22:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('suggested_workouts', '0002_auto_20210304_2241'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('workouts', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='RememberMe',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('remember_me', models.CharField(max_length=500)),
],
),
migrations.AddField(
model_name='exerciseinstance',
name='suggested_workout',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='suggested_exercise_instances', to='suggested_workouts.suggestedworkout'),
),
migrations.AddField(
model_name='workout',
name='planned',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='workoutfile',
name='suggested_workout',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='suggested_workout_files', to='suggested_workouts.suggestedworkout'),
),
migrations.AlterField(
model_name='exerciseinstance',
name='workout',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='exercise_instances', to='workouts.workout'),
),
migrations.AlterField(
model_name='workoutfile',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='workout_files', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='workoutfile',
name='workout',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='files', to='workouts.workout'),
),
]
......@@ -142,7 +142,9 @@ class WorkoutList(
# - The workout has coach visibility and the requesting user is the owner's coach
qs = Workout.objects.filter(
Q(visibility="PU")
| Q(owner=self.request.user)
| (Q(visibility="CO") & Q(owner__coach=self.request.user))
| (Q(visibility= "PR") & Q(owner=self.request.user))
).distinct()
# Check if the planned workout has happened
if len(qs) > 0:
......
......@@ -6,3 +6,4 @@ node_modules/
# Generated by Cordova
#/plugins/
platforms/browser/www/
{
"baseUrl": "http://localhost:8001"
}
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
\ No newline at end of file
[
{
"model": "workouts.exercise",
"pk": 1,
"fields": {
"name": "Push-up",
"description": "A push-up (or press-up in British English) is a common calisthenics exercise beginning from the prone position.",
"unit": "reps"
}
},
{
"model": "workouts.exercise",
"pk": 2,
"fields": {
"name": "Crunch",
"description": "The crunch is one of the most popular abdominal exercises.",
"unit": "reps"
}
},
{
"model": "workouts.exercise",
"pk": 3,
"fields": {
"name": "Plank",
"description": "The plank is an isometric core strength exercise that involves maintaining a position similar to a push-up for the maximum possible time.",
"unit": "seconds"
}
}
]
\ No newline at end of file
[
{
"model": "suggested_workouts.suggestedworkout",
"pk": 1,
"fields": {
"name": "Suggested Workout Seed",
"date": null,
"notes": "heiheihei",
"coach": 1,
"athlete": 2,
"status": "p"
}
}
]
\ No newline at end of file
[
{
"model": "users.user",
"pk": 1,
"fields": {
"password": "pbkdf2_sha256$216000$z0k3ideAq6Zn$mlC8XmI/+IFigImw7SGhQ+ffTutLvbtCcewgDgfmzMg=",
"last_login": null,
"is_superuser": false,
"username": "coach",
"first_name": "",
"last_name": "",
"email": "coach@hei.no",
"is_staff": false,
"is_active": true,
"date_joined": "2021-03-06T13:30:38.062Z",
"coach": null,
"phone_number": "90909",
"country": "uuu",
"city": "uuu",
"street_address": "uu",
"groups": [],
"user_permissions": []
}
},
{
"model": "users.user",
"pk": 2,
"fields": {
"password": "pbkdf2_sha256$216000$cDkq1l1xAvqV$C/FxUDUzeqMSpc7PuaVwImucY6cFM/Ju9CMguJTclJQ=",
"last_login": null,
"is_superuser": false,
"username": "athlete",
"first_name": "",
"last_name": "",
"email": "athlete@hei.no",
"is_staff": false,
"is_active": true,
"date_joined": "2021-03-06T13:30:56.670Z",
"coach": 1,
"phone_number": "99",
"country": "hh",
"city": "hhh",
"street_address": "h",
"groups": [],
"user_permissions": []
}
},
{
"model": "users.offer",
"pk": 1,
"fields": {
"owner": 1,
"recipient": 2,
"status": "d",
"timestamp": "2021-03-06T13:31:08.471Z"
}
},
{
"model": "workouts.exercise",
"pk": 1,
"fields": {
"name": "Push-up",
"description": "A push-up (or press-up in British English) is a common calisthenics exercise beginning from the prone position.",
"unit": "reps"
}
},
{
"model": "workouts.exercise",
"pk": 2,
"fields": {
"name": "Crunch",
"description": "The crunch is one of the most popular abdominal exercises.",
"unit": "reps"
}
},
{
"model": "workouts.exercise",
"pk": 3,
"fields": {
"name": "Plank",
"description": "The plank is an isometric core strength exercise that involves maintaining a position similar to a push-up for the maximum possible time.",
"unit": "seconds"
}
}
]
[
{
"model": "workouts.workout",
"pk": 1,
"fields": {
"name": "Workout Private - Coach",
"date": "2021-03-01T23:03:00Z",
"notes": "Hei",
"owner": 1,
"planned": false,
"visibility": "PR"
}
},
{
"model": "workouts.workout",
"pk": 2,
"fields": {
"name": "Workout Visible for Coach",
"date": "2021-03-01T23:05:00Z",
"notes": "dddd",
"owner": 2,
"planned": false,
"visibility": "CO"
}
},
{
"model": "workouts.workout",
"pk": 3,
"fields": {
"name": "Workout Public - Coach",
"date": "2021-03-06T23:09:00Z",
"notes": "dddd",
"owner": 1,
"planned": false,
"visibility": "PU"
}
}
]
\ No newline at end of file
/// <reference types="cypress" />
context('Actions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})
// https://on.cypress.io/interacting-with-elements
it('.type() - type into a DOM element', () => {
// https://on.cypress.io/type
cy.get('.action-email')
.type('fake@email.com').should('have.value', 'fake@email.com')
// .type() with special character sequences
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
.type('{del}{selectall}{backspace}')
// .type() with key modifiers
.type('{alt}{option}') //these are equivalent
.type('{ctrl}{control}') //these are equivalent
.type('{meta}{command}{cmd}') //these are equivalent
.type('{shift}')
// Delay each keypress by 0.1 sec
.type('slow.typing@email.com', { delay: 100 })
.should('have.value', 'slow.typing@email.com')
cy.get('.action-disabled')
// Ignore error checking prior to type
// like whether the input is visible or disabled
.type('disabled error checking', { force: true })
.should('have.value', 'disabled error checking')
})
it('.focus() - focus on a DOM element', () => {
// https://on.cypress.io/focus
cy.get('.action-focus').focus()
.should('have.class', 'focus')
.prev().should('have.attr', 'style', 'color: orange;')
})
it('.blur() - blur off a DOM element', () => {
// https://on.cypress.io/blur
cy.get('.action-blur').type('About to blur').blur()
.should('have.class', 'error')
.prev().should('have.attr', 'style', 'color: red;')
})
it('.clear() - clears an input or textarea element', () => {
// https://on.cypress.io/clear
cy.get('.action-clear').type('Clear this text')
.should('have.value', 'Clear this text')
.clear()
.should('have.value', '')
})
it('.submit() - submit a form', () => {
// https://on.cypress.io/submit
cy.get('.action-form')
.find('[type="text"]').type('HALFOFF')
cy.get('.action-form').submit()
.next().should('contain', 'Your form has been submitted!')
})
it('.click() - click on a DOM element', () => {
// https://on.cypress.io/click
cy.get('.action-btn').click()
// You can click on 9 specific positions of an element:
// -----------------------------------
// | topLeft top topRight |
// | |
// | |
// | |
// | left center right |