diff options
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/projects.html | 16 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/tests.py | 108 |
2 files changed, 111 insertions, 13 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/projects.html b/bitbake/lib/toaster/toastergui/templates/projects.html index c2d77b5a37..a7192c2d72 100644 --- a/bitbake/lib/toaster/toastergui/templates/projects.html +++ b/bitbake/lib/toaster/toastergui/templates/projects.html | |||
@@ -36,17 +36,27 @@ | |||
36 | {% else %} {# We have builds to display #} | 36 | {% else %} {# We have builds to display #} |
37 | {% include "basetable_top.html" %} | 37 | {% include "basetable_top.html" %} |
38 | {% for o in objects %} | 38 | {% for o in objects %} |
39 | <tr class="data"> | 39 | <tr class="data" data-project="{{ o.id }}"> |
40 | <td><a href="{% url 'project' o.id %}">{{o.name}}</a></td> | 40 | <td><a href="{% url 'project' o.id %}">{{o.name}}</a></td> |
41 | <td class="updated"><a href="{% url 'project' o.id %}">{{o.updated|date:"d/m/y H:i"}}</a></td> | 41 | <td class="updated"><a href="{% url 'project' o.id %}">{{o.updated|date:"d/m/y H:i"}}</a></td> |
42 | <td> | 42 | <td data-project-field="release"> |
43 | {% if o.release %} | 43 | {% if o.release %} |
44 | <a href="{% url 'project' o.id %}#project-details">{{o.release.name}}</a> | 44 | <a href="{% url 'project' o.id %}#project-details">{{o.release.name}}</a> |
45 | {% elif o.is_default %} | ||
46 | <span class="muted">Not applicable</span> | ||
47 | <i class="icon-question-sign get-help hover-help" title="" data-original-title="This project does not have a release set. It simply collects information about the builds you start from the command line while Toaster is running" style="visibility: hidden;"></i> | ||
45 | {% else %} | 48 | {% else %} |
46 | No release available | 49 | No release available |
47 | {% endif %} | 50 | {% endif %} |
48 | </td> | 51 | </td> |
49 | <td><a href="{% url 'project' o.id %}#machine-distro">{{o.get_current_machine_name}}</a></td> | 52 | <td data-project-field="machine"> |
53 | {% if o.is_default %} | ||
54 | <span class="muted">Not applicable</span> | ||
55 | <i class="icon-question-sign get-help hover-help" title="" data-original-title="This project does not have a machine set. It simply collects information about the builds you start from the command line while Toaster is running" style="visibility: hidden;"></i> | ||
56 | {% else %} | ||
57 | <a href="{% url 'project' o.id %}#machine-distro">{{o.get_current_machine_name}}</a> | ||
58 | {% endif %} | ||
59 | </td> | ||
50 | {% if o.get_number_of_builds == 0 %} | 60 | {% if o.get_number_of_builds == 0 %} |
51 | <td class="muted">{{o.get_number_of_builds}}</td> | 61 | <td class="muted">{{o.get_number_of_builds}}</td> |
52 | <td class="loutcome"></td> | 62 | <td class="loutcome"></td> |
diff --git a/bitbake/lib/toaster/toastergui/tests.py b/bitbake/lib/toaster/toastergui/tests.py index 9156cc8952..d278d63aa1 100644 --- a/bitbake/lib/toaster/toastergui/tests.py +++ b/bitbake/lib/toaster/toastergui/tests.py | |||
@@ -29,7 +29,7 @@ from django.utils import timezone | |||
29 | from orm.models import Project, Release, BitbakeVersion, Package | 29 | from orm.models import Project, Release, BitbakeVersion, Package |
30 | from orm.models import ReleaseLayerSourcePriority, LayerSource, Layer, Build | 30 | from orm.models import ReleaseLayerSourcePriority, LayerSource, Layer, Build |
31 | from orm.models import Layer_Version, Recipe, Machine, ProjectLayer, Target | 31 | from orm.models import Layer_Version, Recipe, Machine, ProjectLayer, Target |
32 | from orm.models import CustomImageRecipe | 32 | from orm.models import CustomImageRecipe, ProjectVariable |
33 | from orm.models import Branch | 33 | from orm.models import Branch |
34 | 34 | ||
35 | from toastergui.tables import SoftwareRecipesTable | 35 | from toastergui.tables import SoftwareRecipesTable |
@@ -430,15 +430,43 @@ class LandingPageTests(TestCase): | |||
430 | class ProjectsPageTests(TestCase): | 430 | class ProjectsPageTests(TestCase): |
431 | """ Tests for projects page """ | 431 | """ Tests for projects page """ |
432 | 432 | ||
433 | PROJECT_NAME = 'cli builds' | 433 | MACHINE_NAME = 'delorean' |
434 | |||
435 | def _add_build_to_default_project(self): | ||
436 | """ Add a build to the default project (not used in all tests) """ | ||
437 | now = timezone.now() | ||
438 | build = Build.objects.create(project=self.default_project, | ||
439 | started_on=now, | ||
440 | completed_on=now) | ||
441 | build.save() | ||
442 | |||
443 | def _add_non_default_project(self): | ||
444 | """ Add another project """ | ||
445 | bbv = BitbakeVersion.objects.create(name="test bbv", giturl="/tmp/", | ||
446 | branch="master", dirpath="") | ||
447 | self.release = Release.objects.create(name="test release", | ||
448 | branch_name="master", | ||
449 | bitbake_version=bbv) | ||
450 | self.project = Project.objects.create_project(PROJECT_NAME, self.release) | ||
451 | self.project.is_default = False | ||
452 | self.project.save() | ||
453 | |||
454 | # fake the MACHINE variable | ||
455 | project_var = ProjectVariable.objects.create(project=self.project, | ||
456 | name='MACHINE', | ||
457 | value=self.MACHINE_NAME) | ||
458 | project_var.save() | ||
434 | 459 | ||
435 | def setUp(self): | 460 | def setUp(self): |
436 | """ Add default project manually """ | 461 | """ Add default project manually """ |
437 | project = Project.objects.create_project(self.PROJECT_NAME, None) | 462 | project = Project.objects.create_project(CLI_BUILDS_PROJECT_NAME, None) |
438 | self.default_project = project | 463 | self.default_project = project |
439 | self.default_project.is_default = True | 464 | self.default_project.is_default = True |
440 | self.default_project.save() | 465 | self.default_project.save() |
441 | 466 | ||
467 | # this project is only set for some of the tests | ||
468 | self.project = None | ||
469 | |||
442 | def test_default_project_hidden(self): | 470 | def test_default_project_hidden(self): |
443 | """ The default project should be hidden if it has no builds """ | 471 | """ The default project should be hidden if it has no builds """ |
444 | params = {"count": 10, "orderby": "updated:-", "page": 1} | 472 | params = {"count": 10, "orderby": "updated:-", "page": 1} |
@@ -446,25 +474,85 @@ class ProjectsPageTests(TestCase): | |||
446 | 474 | ||
447 | self.assertTrue(not('tr class="data"' in response.content), | 475 | self.assertTrue(not('tr class="data"' in response.content), |
448 | 'should be no project rows in the page') | 476 | 'should be no project rows in the page') |
449 | self.assertTrue(not(self.PROJECT_NAME in response.content), | 477 | self.assertTrue(not(CLI_BUILDS_PROJECT_NAME in response.content), |
450 | 'default project "cli builds" should not be in page') | 478 | 'default project "cli builds" should not be in page') |
451 | 479 | ||
452 | def test_default_project_has_build(self): | 480 | def test_default_project_has_build(self): |
453 | """ The default project should be shown if it has builds """ | 481 | """ The default project should be shown if it has builds """ |
454 | now = timezone.now() | 482 | self._add_build_to_default_project() |
455 | build = Build.objects.create(project=self.default_project, | ||
456 | started_on=now, | ||
457 | completed_on=now) | ||
458 | build.save() | ||
459 | 483 | ||
460 | params = {"count": 10, "orderby": "updated:-", "page": 1} | 484 | params = {"count": 10, "orderby": "updated:-", "page": 1} |
461 | response = self.client.get(reverse('all-projects'), params) | 485 | response = self.client.get(reverse('all-projects'), params) |
462 | 486 | ||
463 | self.assertTrue('tr class="data"' in response.content, | 487 | self.assertTrue('tr class="data"' in response.content, |
464 | 'should be a project row in the page') | 488 | 'should be a project row in the page') |
465 | self.assertTrue(self.PROJECT_NAME in response.content, | 489 | self.assertTrue(CLI_BUILDS_PROJECT_NAME in response.content, |
466 | 'default project "cli builds" should be in page') | 490 | 'default project "cli builds" should be in page') |
467 | 491 | ||
492 | def test_default_project_release(self): | ||
493 | """ | ||
494 | The release for the default project should display as | ||
495 | 'Not applicable' | ||
496 | """ | ||
497 | # need a build, otherwise project doesn't display at all | ||
498 | self._add_build_to_default_project() | ||
499 | |||
500 | # another project to test, which should show release | ||
501 | self._add_non_default_project() | ||
502 | |||
503 | response = self.client.get(reverse('all-projects'), follow=True) | ||
504 | soup = BeautifulSoup(response.content) | ||
505 | |||
506 | # check the release cell for the default project | ||
507 | attrs = {'data-project': str(self.default_project.id)} | ||
508 | rows = soup.find_all('tr', attrs=attrs) | ||
509 | self.assertEqual(len(rows), 1, 'should be one row for default project') | ||
510 | cells = rows[0].find_all('td', attrs={'data-project-field': 'release'}) | ||
511 | self.assertEqual(len(cells), 1, 'should be one release cell') | ||
512 | text = cells[0].select('span.muted')[0].text | ||
513 | self.assertEqual(text, 'Not applicable', | ||
514 | 'release should be not applicable for default project') | ||
515 | |||
516 | # check the link in the release cell for the other project | ||
517 | attrs = {'data-project': str(self.project.id)} | ||
518 | rows = soup.find_all('tr', attrs=attrs) | ||
519 | cells = rows[0].find_all('td', attrs={'data-project-field': 'release'}) | ||
520 | text = cells[0].select('a')[0].text | ||
521 | self.assertEqual(text, self.release.name, | ||
522 | 'release name should be shown for non-default project') | ||
523 | |||
524 | def test_default_project_machine(self): | ||
525 | """ | ||
526 | The machine for the default project should display as | ||
527 | 'Not applicable' | ||
528 | """ | ||
529 | # need a build, otherwise project doesn't display at all | ||
530 | self._add_build_to_default_project() | ||
531 | |||
532 | # another project to test, which should show machine | ||
533 | self._add_non_default_project() | ||
534 | |||
535 | response = self.client.get(reverse('all-projects'), follow=True) | ||
536 | soup = BeautifulSoup(response.content) | ||
537 | |||
538 | # check the machine cell for the default project | ||
539 | attrs = {'data-project': str(self.default_project.id)} | ||
540 | rows = soup.find_all('tr', attrs=attrs) | ||
541 | self.assertEqual(len(rows), 1, 'should be one row for default project') | ||
542 | cells = rows[0].find_all('td', attrs={'data-project-field': 'machine'}) | ||
543 | self.assertEqual(len(cells), 1, 'should be one machine cell') | ||
544 | text = cells[0].select('span.muted')[0].text | ||
545 | self.assertEqual(text, 'Not applicable', | ||
546 | 'machine should be not applicable for default project') | ||
547 | |||
548 | # check the link in the machine cell for the other project | ||
549 | attrs = {'data-project': str(self.project.id)} | ||
550 | rows = soup.find_all('tr', attrs=attrs) | ||
551 | cells = rows[0].find_all('td', attrs={'data-project-field': 'machine'}) | ||
552 | text = cells[0].select('a')[0].text | ||
553 | self.assertEqual(text, self.MACHINE_NAME, | ||
554 | 'machine name should be shown for non-default project') | ||
555 | |||
468 | class ProjectBuildsPageTests(TestCase): | 556 | class ProjectBuildsPageTests(TestCase): |
469 | """ Test data at /project/X/builds is displayed correctly """ | 557 | """ Test data at /project/X/builds is displayed correctly """ |
470 | 558 | ||