diff options
6 files changed, 82 insertions, 11 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html index 640bc47bcc..3f277909d7 100644 --- a/bitbake/lib/toaster/toastergui/templates/base.html +++ b/bitbake/lib/toaster/toastergui/templates/base.html | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
| 2 | {% load static %} | 2 | {% load static %} |
| 3 | {% load projecttags %} | 3 | {% load projecttags %} |
| 4 | {% load project_url_tag %} | ||
| 4 | <html lang="en"> | 5 | <html lang="en"> |
| 5 | <head> | 6 | <head> |
| 6 | <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> | 7 | <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> |
| @@ -35,7 +36,7 @@ | |||
| 35 | projectsTypeAheadUrl: {% url 'xhr_projectstypeahead' as prjurl%}{{prjurl|json}}, | 36 | projectsTypeAheadUrl: {% url 'xhr_projectstypeahead' as prjurl%}{{prjurl|json}}, |
| 36 | {% if project.id %} | 37 | {% if project.id %} |
| 37 | projectId : {{project.id}}, | 38 | projectId : {{project.id}}, |
| 38 | projectPageUrl : {% url 'project' project.id as purl%}{{purl|json}}, | 39 | projectPageUrl : {% url 'project' project.id as purl %}{{purl|json}}, |
| 39 | projectName : {{project.name|json}}, | 40 | projectName : {{project.name|json}}, |
| 40 | recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}}, | 41 | recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}}, |
| 41 | layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}}, | 42 | layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}}, |
| @@ -133,7 +134,7 @@ | |||
| 133 | <h6>Project:</h6> | 134 | <h6>Project:</h6> |
| 134 | <span id="project"> | 135 | <span id="project"> |
| 135 | {% if project.id %} | 136 | {% if project.id %} |
| 136 | <a class="lead" href="{% url 'project' project.id %}">{{project.name}}</a> | 137 | <a class="lead" href="{% project_url project %}">{{project.name}}</a> |
| 137 | {% else %} | 138 | {% else %} |
| 138 | <a class="lead" href="#"></a> | 139 | <a class="lead" href="#"></a> |
| 139 | {% endif %} | 140 | {% endif %} |
diff --git a/bitbake/lib/toaster/toastergui/templates/builds.html b/bitbake/lib/toaster/toastergui/templates/builds.html index 2b35b010ed..6fbaf98ae0 100644 --- a/bitbake/lib/toaster/toastergui/templates/builds.html +++ b/bitbake/lib/toaster/toastergui/templates/builds.html | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | {% load static %} | 3 | {% load static %} |
| 4 | {% load projecttags %} | 4 | {% load projecttags %} |
| 5 | {% load project_url_tag %} | ||
| 5 | {% load humanize %} | 6 | {% load humanize %} |
| 6 | 7 | ||
| 7 | {% block extraheadcontent %} | 8 | {% block extraheadcontent %} |
| @@ -104,7 +105,7 @@ | |||
| 104 | {% endif %} | 105 | {% endif %} |
| 105 | </td> | 106 | </td> |
| 106 | <td> | 107 | <td> |
| 107 | <a href="{% url 'project' build.project.id %}">{{build.project.name}}</a> | 108 | <a href="{% project_url build.project %}">{{build.project.name}}</a> |
| 108 | </td> | 109 | </td> |
| 109 | </tr> | 110 | </tr> |
| 110 | 111 | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html index 5e96b39121..b29f650f5d 100644 --- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html +++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | {% load static %} | 1 | {% load static %} |
| 2 | {% load projecttags %} | 2 | {% load projecttags %} |
| 3 | {% load project_url_tag %} | ||
| 3 | {% load humanize %} | 4 | {% load humanize %} |
| 4 | 5 | ||
| 5 | |||
| 6 | {%if mru and mru.count > 0%} | 6 | {%if mru and mru.count > 0%} |
| 7 | 7 | ||
| 8 | {%if mrb_type == 'project' %} | 8 | {%if mrb_type == 'project' %} |
| @@ -22,7 +22,7 @@ | |||
| 22 | {% if mrb_type != 'project' %} | 22 | {% if mrb_type != 'project' %} |
| 23 | project-name"> | 23 | project-name"> |
| 24 | <span class="label {%if build.outcome == build.SUCCEEDED%}label-success{%elif build.outcome == build.FAILED%}label-important{%else%}label-info{%endif%}"> | 24 | <span class="label {%if build.outcome == build.SUCCEEDED%}label-success{%elif build.outcome == build.FAILED%}label-important{%else%}label-info{%endif%}"> |
| 25 | <a href={% url 'project' build.project.pk %}> | 25 | <a href={% project_url build.project %}> |
| 26 | {{build.project.name}} | 26 | {{build.project.name}} |
| 27 | </a> | 27 | </a> |
| 28 | </span> | 28 | </span> |
| @@ -106,7 +106,7 @@ | |||
| 106 | pull-right" | 106 | pull-right" |
| 107 | onclick='scheduleBuild({% url 'projectbuilds' build.project.id as bpi %}{{bpi|json}}, | 107 | onclick='scheduleBuild({% url 'projectbuilds' build.project.id as bpi %}{{bpi|json}}, |
| 108 | {{build.project.name|json}}, | 108 | {{build.project.name|json}}, |
| 109 | {% url 'project' build.project.id as bpurl %}{{bpurl|json}}, | 109 | {% url 'project' build.project.id as purl %}{{purl|json}}, |
| 110 | {{build.target_set.all|get_tasks|json}})'> | 110 | {{build.target_set.all|get_tasks|json}})'> |
| 111 | 111 | ||
| 112 | Run again | 112 | Run again |
diff --git a/bitbake/lib/toaster/toastergui/templates/projects.html b/bitbake/lib/toaster/toastergui/templates/projects.html index a7192c2d72..7c612e8c43 100644 --- a/bitbake/lib/toaster/toastergui/templates/projects.html +++ b/bitbake/lib/toaster/toastergui/templates/projects.html | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | {% load static %} | 3 | {% load static %} |
| 4 | {% load projecttags %} | 4 | {% load projecttags %} |
| 5 | {% load project_url_tag %} | ||
| 5 | {% load humanize %} | 6 | {% load humanize %} |
| 6 | 7 | ||
| 7 | {% block pagecontent %} | 8 | {% block pagecontent %} |
| @@ -37,8 +38,10 @@ | |||
| 37 | {% include "basetable_top.html" %} | 38 | {% include "basetable_top.html" %} |
| 38 | {% for o in objects %} | 39 | {% for o in objects %} |
| 39 | <tr class="data" data-project="{{ o.id }}"> | 40 | <tr class="data" data-project="{{ o.id }}"> |
| 40 | <td><a href="{% url 'project' o.id %}">{{o.name}}</a></td> | 41 | <td data-project-field="name"> |
| 41 | <td class="updated"><a href="{% url 'project' o.id %}">{{o.updated|date:"d/m/y H:i"}}</a></td> | 42 | <a href="{% project_url o %}">{{o.name}}</a> |
| 43 | </td> | ||
| 44 | <td class="updated"><a href="{% project_url o %}">{{o.updated|date:"d/m/y H:i"}}</a></td> | ||
| 42 | <td data-project-field="release"> | 45 | <td data-project-field="release"> |
| 43 | {% if o.release %} | 46 | {% if o.release %} |
| 44 | <a href="{% url 'project' o.id %}#project-details">{{o.release.name}}</a> | 47 | <a href="{% url 'project' o.id %}#project-details">{{o.release.name}}</a> |
diff --git a/bitbake/lib/toaster/toastergui/templatetags/project_url_tag.py b/bitbake/lib/toaster/toastergui/templatetags/project_url_tag.py new file mode 100644 index 0000000000..04770ac6a8 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templatetags/project_url_tag.py | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | from django import template | ||
| 2 | from django.core.urlresolvers import reverse | ||
| 3 | |||
| 4 | register = template.Library() | ||
| 5 | |||
| 6 | def project_url(parser, token): | ||
| 7 | """ | ||
| 8 | Create a URL for a project's main page; | ||
| 9 | for non-default projects, this is the configuration page; | ||
| 10 | for the default project, this is the project builds page | ||
| 11 | """ | ||
| 12 | try: | ||
| 13 | tag_name, project = token.split_contents() | ||
| 14 | except ValueError: | ||
| 15 | raise template.TemplateSyntaxError( | ||
| 16 | "%s tag requires exactly one argument" % tag_name | ||
| 17 | ) | ||
| 18 | return ProjectUrlNode(project) | ||
| 19 | |||
| 20 | class ProjectUrlNode(template.Node): | ||
| 21 | def __init__(self, project): | ||
| 22 | self.project = template.Variable(project) | ||
| 23 | |||
| 24 | def render(self, context): | ||
| 25 | try: | ||
| 26 | project = self.project.resolve(context) | ||
| 27 | if project.is_default: | ||
| 28 | return reverse('projectbuilds', args=(project.id,)) | ||
| 29 | else: | ||
| 30 | return reverse('project', args=(project.id,)) | ||
| 31 | except template.VariableDoesNotExist: | ||
| 32 | return '' | ||
| 33 | |||
| 34 | register.tag('project_url', project_url) | ||
diff --git a/bitbake/lib/toaster/toastergui/tests.py b/bitbake/lib/toaster/toastergui/tests.py index c725fc827d..3753748b75 100644 --- a/bitbake/lib/toaster/toastergui/tests.py +++ b/bitbake/lib/toaster/toastergui/tests.py | |||
| @@ -428,8 +428,8 @@ class LandingPageTests(TestCase): | |||
| 428 | self.assertTrue('/builds' in response.url, | 428 | self.assertTrue('/builds' in response.url, |
| 429 | 'should redirect to builds') | 429 | 'should redirect to builds') |
| 430 | 430 | ||
| 431 | class ProjectsPageTests(TestCase): | 431 | class AllProjectsPageTests(TestCase): |
| 432 | """ Tests for projects page """ | 432 | """ Tests for projects page /projects/ """ |
| 433 | 433 | ||
| 434 | MACHINE_NAME = 'delorean' | 434 | MACHINE_NAME = 'delorean' |
| 435 | 435 | ||
| @@ -554,6 +554,38 @@ class ProjectsPageTests(TestCase): | |||
| 554 | self.assertEqual(text, self.MACHINE_NAME, | 554 | self.assertEqual(text, self.MACHINE_NAME, |
| 555 | 'machine name should be shown for non-default project') | 555 | 'machine name should be shown for non-default project') |
| 556 | 556 | ||
| 557 | def test_project_page_links(self): | ||
| 558 | """ | ||
| 559 | Test that links for the default project point to the builds | ||
| 560 | page /projects/X/builds for that project, and that links for | ||
| 561 | other projects point to their configuration pages /projects/X/ | ||
| 562 | """ | ||
| 563 | |||
| 564 | # need a build, otherwise project doesn't display at all | ||
| 565 | self._add_build_to_default_project() | ||
| 566 | |||
| 567 | # another project to test, which should show machine | ||
| 568 | self._add_non_default_project() | ||
| 569 | |||
| 570 | response = self.client.get(reverse('all-projects'), follow=True) | ||
| 571 | soup = BeautifulSoup(response.content) | ||
| 572 | |||
| 573 | # link for default project | ||
| 574 | row = soup.find('tr', attrs={'data-project': self.default_project.id}) | ||
| 575 | cell = row.find('td', attrs={'data-project-field': 'name'}) | ||
| 576 | url = cell.find('a')['href'] | ||
| 577 | expected_url = reverse('projectbuilds', args=(self.default_project.id,)) | ||
| 578 | self.assertEqual(url, expected_url, | ||
| 579 | 'link on default project name should point to builds') | ||
| 580 | |||
| 581 | # link for other project | ||
| 582 | row = soup.find('tr', attrs={'data-project': self.project.id}) | ||
| 583 | cell = row.find('td', attrs={'data-project-field': 'name'}) | ||
| 584 | url = cell.find('a')['href'] | ||
| 585 | expected_url = reverse('project', args=(self.project.id,)) | ||
| 586 | self.assertEqual(url, expected_url, | ||
| 587 | 'link on project name should point to configuration') | ||
| 588 | |||
| 557 | class ProjectBuildsPageTests(TestCase): | 589 | class ProjectBuildsPageTests(TestCase): |
| 558 | """ Test data at /project/X/builds is displayed correctly """ | 590 | """ Test data at /project/X/builds is displayed correctly """ |
| 559 | 591 | ||
| @@ -650,7 +682,7 @@ class ProjectBuildsPageTests(TestCase): | |||
| 650 | self.assertEqual(len(result), 2) | 682 | self.assertEqual(len(result), 2) |
| 651 | 683 | ||
| 652 | class AllBuildsPageTests(TestCase): | 684 | class AllBuildsPageTests(TestCase): |
| 653 | """ Tests for all builds page """ | 685 | """ Tests for all builds page /builds/ """ |
| 654 | 686 | ||
| 655 | def setUp(self): | 687 | def setUp(self): |
| 656 | bbv = BitbakeVersion.objects.create(name="bbv1", giturl="/tmp/", | 688 | bbv = BitbakeVersion.objects.create(name="bbv1", giturl="/tmp/", |
