diff options
| -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 | ||
