Skip to content
This repository has been archived by the owner on Jul 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1113 from katieworton/failures_only
Browse files Browse the repository at this point in the history
Add user preference for failures only
  • Loading branch information
chaws authored Nov 22, 2023
2 parents 59d0963 + b5bbdc9 commit 48bef6c
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 5 deletions.
38 changes: 38 additions & 0 deletions squad/core/migrations/0169_userpreferences.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 4.2.4 on 2023-11-21 17:54

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),
("core", "0168_add_group_settings"),
]

operations = [
migrations.CreateModel(
name="UserPreferences",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("display_failures_only", models.BooleanField(default=True)),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]
5 changes: 5 additions & 0 deletions squad/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ class Meta:
proxy = True


class UserPreferences(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
display_failures_only = models.BooleanField(default=True)


class ProjectManager(models.Manager):

def accessible_to(self, user):
Expand Down
1 change: 1 addition & 0 deletions squad/frontend/templates/squad/user_settings/base.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<li class="list-group-item {{active("settings-projects")}}"><a href="{{url('settings-projects')}}">{{ _('Personal projects') }}</a></li>
<li class="list-group-item {{active("settings-api-token")}}"><a href="{{url('settings-api-token')}}">{{ _('API token') }}</a></li>
<li class="list-group-item {{active("settings-subscriptions")}}"><a href="{{url('settings-subscriptions')}}">{{ _('Subscriptions') }}</a></li>
<li class="list-group-item {{active("settings-user-preferences")}}"><a href="{{url('settings-user-preferences')}}">{{ _('User Preferences') }}</a></li>
</ul>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "squad/user_settings/base.jinja2" %}
{% block settings %}
<h1>{{ _('User Preferences') }}</h1>

<form method="POST">
{{ csrf_input }}
{{crispy(form)}}
<input class='btn btn-primary' type="submit" value="{{ _('Save') }}" />
</form>

{% endblock %}

27 changes: 26 additions & 1 deletion squad/frontend/user_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from rest_framework.authtoken.models import Token


from squad.core.models import Group, Project, Subscription, UserNamespace
from squad.core.models import Group, Project, Subscription, UserNamespace, UserPreferences
from squad.frontend.views import get_user_preferences


logger = logging.getLogger()
Expand All @@ -30,6 +31,29 @@ class Meta:
fields = ['first_name', 'last_name', 'email']


class UserPreferencesForm(forms.ModelForm):
class Meta:
model = UserPreferences
fields = ['display_failures_only']


@login_required
def user_preferences(request):
preferences = get_user_preferences(request.user)
if request.method == "POST":
form = UserPreferencesForm(request.POST, instance=preferences)
if form.is_valid():
form.save()
return redirect(request.path)
else:
form = UserPreferencesForm(instance=preferences)

context = {
'form': form,
}
return render(request, 'squad/user_settings/user_preferences.jinja2', context)


@login_required
def profile(request):
if request.method == "POST":
Expand Down Expand Up @@ -126,6 +150,7 @@ def projects(request):
url('^profile/$', profile, name='settings-profile'),
url('^api-token/$', api_token, name='settings-api-token'),
url('^subscriptions/$', subscriptions, name='settings-subscriptions'),
url('^user-preferences/$', user_preferences, name='settings-user-preferences'),
url(r'^remove-subscription/(?P<id>\d+)$', remove_subscription, name='settings-subscription-remove'),
url(r'^remove-subscription/$', remove_subscription, name='settings-subscription-remove-post'),
url('^projects/$', projects, name='settings-projects'),
Expand Down
20 changes: 18 additions & 2 deletions squad/frontend/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from squad.ci.models import TestJob
from squad.core.models import Group, Metric, ProjectStatus, Status, MetricThreshold, KnownIssue, Test
from squad.core.models import Build, Subscription, TestRun, SuiteMetadata
from squad.core.models import Build, Subscription, TestRun, SuiteMetadata, UserPreferences
from squad.core.queries import get_metric_data, test_confidence
from squad.frontend.queries import get_metrics_list
from squad.frontend.utils import file_type, alphanum_sort
Expand All @@ -29,6 +29,18 @@ def __init__(self, date, days):
super(BuildDeleted, self).__init__(msg)


def get_user_preferences(user):
if user.is_authenticated:
try:
preferences = UserPreferences.objects.get(user=user)
except UserPreferences.DoesNotExist:
preferences = UserPreferences.objects.create(user=user)
else:
return None

return preferences


def get_build(project, version):
if version == 'latest-finished':
status = ProjectStatus.objects.prefetch_related('build').filter(
Expand Down Expand Up @@ -362,7 +374,11 @@ def build(request, group_slug, project_slug, version):
project = request.project
build = get_build(project, version)

failures_only = request.GET.get('failures_only', 'true')
user_default_failures_only = ""
user_preferences = get_user_preferences(request.user)
if user_preferences:
user_default_failures_only = str(user_preferences.display_failures_only).lower()
failures_only = request.GET.get('failures_only', user_default_failures_only)
if failures_only not in ['true', 'false']:
failures_only = 'true'

Expand Down
42 changes: 40 additions & 2 deletions test/frontend/test_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from django.test import Client
import json

from squad.frontend.views import get_user_preferences

tests_file = {
("suite1/test%d" % i): "fail" for i in range(0, 50)
}
Expand Down Expand Up @@ -148,18 +150,54 @@ def setUp(self):

def test_table_layout(self):
response = self.client.get('/mygroup/myproject/build/1/?results_layout=table')
self.assertIn("onclick=\"window.location = \'?results_layout=table&amp;failures_only=false#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_table_layout_failures_only(self):
def test_table_layout_failures_only_false(self):
response = self.client.get('/mygroup/myproject/build/1/?results_layout=table&failures_only=false')
self.assertIn("onclick=\"window.location = \'?results_layout=table&amp;failures_only=true#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_table_layout_failures_only_true(self):
response = self.client.get('/mygroup/myproject/build/1/?results_layout=table&failures_only=true')
self.assertIn("onclick=\"window.location = \'?results_layout=table&amp;failures_only=false#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_envbox_layout(self):
response = self.client.get('/mygroup/myproject/build/1/?results_layout=envbox')
self.assertIn("onclick=\"window.location = \'?results_layout=envbox&amp;failures_only=false#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_envbox_layout_failures_only(self):
def test_envbox_layout_failures_only_false(self):
response = self.client.get('/mygroup/myproject/build/1/?results_layout=envbox&failures_only=false')
self.assertIn("onclick=\"window.location = \'?results_layout=envbox&amp;failures_only=true#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_envbox_layout_failures_only_true(self):
response = self.client.get('/mygroup/myproject/build/1/?results_layout=envbox&failures_only=true')
self.assertIn("onclick=\"window.location = \'?results_layout=envbox&amp;failures_only=false#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_failures_only_user_preference_false(self):
self.user = models.User.objects.create(username='theuser')
self.client = Client()
self.client.force_login(self.user)
self.user_preferences = get_user_preferences(user=self.user)
self.user_preferences.display_failures_only = False
self.user_preferences.save()
response = self.client.get('/mygroup/myproject/build/1/')
self.assertIn("onclick=\"window.location = \'?failures_only=true#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_failures_only_user_preference_true(self):
self.user = models.User.objects.create(username='theuser')
self.client = Client()
self.client.force_login(self.user)
self.user_preferences = get_user_preferences(user=self.user)
self.user_preferences.display_failures_only = True
self.user_preferences.save()
response = self.client.get('/mygroup/myproject/build/1/')
self.assertIn("onclick=\"window.location = \'?failures_only=false#test-results'\"", response.content.decode("utf-8"))
self.assertEqual(200, response.status_code)

def test_suitebox_layout(self):
Expand Down

0 comments on commit 48bef6c

Please sign in to comment.