diff --git a/app/Http/Controllers/BuildController.php b/app/Http/Controllers/BuildController.php
index 2f847826c9..a7befb8825 100644
--- a/app/Http/Controllers/BuildController.php
+++ b/app/Http/Controllers/BuildController.php
@@ -127,6 +127,16 @@ public function summary(int $build_id): View
]);
}
+ public function comments(int $build_id): View
+ {
+ $this->setBuildById($build_id);
+
+ return $this->vue('build-comments-page', 'Comments', [
+ 'build-id' => $this->build->Id,
+ 'user-id' => Auth::id() ?? 0,
+ ]);
+ }
+
public function update(int $build_id): View
{
$this->setBuildById($build_id);
diff --git a/app/cdash/tests/CMakeLists.txt b/app/cdash/tests/CMakeLists.txt
index b4616aab97..98fee9613e 100644
--- a/app/cdash/tests/CMakeLists.txt
+++ b/app/cdash/tests/CMakeLists.txt
@@ -429,6 +429,8 @@ add_browser_test(/Browser/Pages/BuildDynamicAnalysisIdPageTest)
add_browser_test(/Browser/Pages/BuildSummaryPageTest)
+add_browser_test(/Browser/Pages/BuildCommentsPageTest)
+
add_browser_test(/Browser/Pages/BuildSidebarComponentTest)
add_browser_test(/Browser/Pages/ProjectSettingsPageTest)
diff --git a/resources/js/angular/views/partials/build.html b/resources/js/angular/views/partials/build.html
index 619119553d..ed5b8dc1a9 100644
--- a/resources/js/angular/views/partials/build.html
+++ b/resources/js/angular/views/partials/build.html
@@ -91,7 +91,7 @@
+ ng-href="builds/{{::build.id}}/comments">
diff --git a/resources/js/vue/app.js b/resources/js/vue/app.js
index ef1038f4f9..83b9fe011c 100755
--- a/resources/js/vue/app.js
+++ b/resources/js/vue/app.js
@@ -29,6 +29,7 @@ const app = Vue.createApp({
BuildFilesPage: Vue.defineAsyncComponent(() => import('./components/BuildFilesPage.vue')),
BuildTargetsPage: Vue.defineAsyncComponent(() => import('./components/BuildTargetsPage.vue')),
BuildInstrumentationPage: Vue.defineAsyncComponent(() => import('./components/BuildInstrumentationPage.vue')),
+ BuildCommentsPage: Vue.defineAsyncComponent(() => import('./components/BuildCommentsPage.vue')),
BuildBuildPage: Vue.defineAsyncComponent(() => import('./components/BuildBuildPage.vue')),
CoverageFilePage: Vue.defineAsyncComponent(() => import('./components/CoverageFilePage.vue')),
BuildCoveragePage: Vue.defineAsyncComponent(() => import('./components/BuildCoveragePage.vue')),
diff --git a/resources/js/vue/components/BuildCommentsPage.vue b/resources/js/vue/components/BuildCommentsPage.vue
new file mode 100644
index 0000000000..3e0d8d402c
--- /dev/null
+++ b/resources/js/vue/components/BuildCommentsPage.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+ Comments ({{ comments ? comments.length : 0 }})
+
+
+
+
+
+
+
+
+ {{ comment.user.firstname }} {{ comment.user.lastname }}
+ You
+
+
+
+
+
+
+
+ No comments yet.
+
+
+
+
+
+
+
+ Add a comment
+
+
+
+
+
+
+
+ Please
log in to add a comment.
+
+
+
+
+
+
+
+
diff --git a/resources/js/vue/components/BuildSummary.vue b/resources/js/vue/components/BuildSummary.vue
index ee7bc324cd..8722f58530 100644
--- a/resources/js/vue/components/BuildSummary.vue
+++ b/resources/js/vue/components/BuildSummary.vue
@@ -418,79 +418,6 @@
-
-
-
- Comments ({{ comments.length }})
-
-
-
-
- {{ comment.user.firstname }} {{ comment.user.lastname }} {{ Utils.formatRelativeTimestamp(comment.timestamp) }}
-
-
-
-
-
-
-
-
-
-
![graph]()
-
-
-
-
-
-
-
@@ -521,7 +448,6 @@ import {
faLink,
} from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';
-import CodeBox from './shared/CodeBox.vue';
import LoadingIndicator from './shared/LoadingIndicator.vue';
import BuildSummaryCard from './shared/BuildSummaryCard.vue';
import BuildSidebar from './shared/BuildSidebar.vue';
@@ -532,7 +458,7 @@ import { DateTime, Duration } from 'luxon';
export default {
name: 'BuildSummary',
- components: {BuildTimeChart, BuildSummaryCard, LoadingIndicator, CodeBox, BuildSidebar, FontAwesomeIcon},
+ components: {BuildTimeChart, BuildSummaryCard, LoadingIndicator, BuildSidebar, FontAwesomeIcon},
props: {
projectId: {
@@ -572,11 +498,6 @@ export default {
cdash: {},
loading: true,
errored: false,
-
- commentText: '',
-
- // Booleans controlling whether a section should be displayed or not.
- showComments: false,
};
},
@@ -711,36 +632,6 @@ export default {
this.loading = false;
},
},
- comments: {
- query: gql`
- query($buildId: ID) {
- build(id: $buildId) {
- id
- comments {
- edges {
- node {
- id
- text
- timestamp
- user {
- id
- firstname
- lastname
- }
- }
- }
- }
- }
- }
- `,
- update: data => data?.build?.comments?.edges,
- variables() {
- return {
- buildId: this.buildId,
- };
- },
- },
-
buildHistory: {
query: gql`
query($projectId: ID, $filters: ProjectBuildsFiltersMultiFilterInput, $onlyParents: Boolean) {
@@ -836,41 +727,6 @@ export default {
},
methods: {
- toggleComments: function() {
- this.showComments = !this.showComments;
- },
-
- addComment: function() {
- this.$apollo
- .mutate({
- mutation: gql`
- mutation createComment($input: CreateCommentInput!) {
- createComment(input: $input) {
- comment {
- id
- }
- }
- }
- `,
- variables: {
- input: {
- buildId: this.buildId,
- text: this.commentText,
- },
- },
- })
- .then(() => {
- // Add the newly created comment to our list.
- this.$apollo.queries.comments.refetch();
- this.commentText = '';
- this.showComments = false;
- })
- .catch(error => {
- // Display the error.
- this.cdash.error = error;
- console.log(error);
- });
- },
},
};
diff --git a/resources/js/vue/components/shared/BuildSidebar.vue b/resources/js/vue/components/shared/BuildSidebar.vue
index 8342e2513c..43cf0d0624 100644
--- a/resources/js/vue/components/shared/BuildSidebar.vue
+++ b/resources/js/vue/components/shared/BuildSidebar.vue
@@ -13,6 +13,15 @@
:disabled="summaryDisabled"
data-test="sidebar-summary"
/>
+
whereNumber('id');
+Route::get('/builds/{id}/comments', 'BuildController@comments')
+ ->whereNumber('id');
Route::permanentRedirect('/build/{id}', url('/builds/{id}'));
Route::get('/buildSummary.php', function (Request $request) {
$buildid = $request->query('buildid');
diff --git a/tests/Browser/Pages/BuildCommentsPageTest.php b/tests/Browser/Pages/BuildCommentsPageTest.php
new file mode 100644
index 0000000000..c722c42514
--- /dev/null
+++ b/tests/Browser/Pages/BuildCommentsPageTest.php
@@ -0,0 +1,119 @@
+project = $this->makePublicProject();
+
+ $this->user = $this->makeNormalUser();
+
+ $this->site = $this->makeSite();
+ $this->updateSiteInfoIfChanged($this->site, new SiteInformation([]));
+ }
+
+ public function tearDown(): void
+ {
+ $this->project->delete();
+ $this->site->delete();
+ $this->user->delete();
+
+ parent::tearDown();
+ }
+
+ public function testLoggedOutUserCanSeeCommentsButNotAdd(): void
+ {
+ /** @var Build $build */
+ $build = $this->project->builds()->create([
+ 'siteid' => $this->site->id,
+ 'name' => Str::uuid()->toString(),
+ 'uuid' => Str::uuid()->toString(),
+ ]);
+
+ /** @var Comment $comment */
+ $comment = $build->comments()->save(Comment::factory()->make([
+ 'userid' => $this->user->id,
+ ]));
+
+ $this->browse(function (Browser $browser) use ($comment, $build): void {
+ $browser->visit("/builds/{$build->id}/comments")
+ ->waitForText($comment->text)
+ ->assertSee($this->user->firstname)
+ ->assertSee($this->user->lastname)
+ ->assertMissing('@comment-text')
+ ->assertMissing('@add-comment')
+ ->assertSee('log in to add a comment')
+ ;
+ });
+ }
+
+ public function testAddComment(): void
+ {
+ /** @var Build $build */
+ $build = $this->project->builds()->create([
+ 'siteid' => $this->site->id,
+ 'name' => Str::uuid()->toString(),
+ 'uuid' => Str::uuid()->toString(),
+ ]);
+
+ $commentText = 'This is a test comment ' . Str::random(10);
+
+ $this->browse(function (Browser $browser) use ($build, $commentText): void {
+ $browser->loginAs($this->user)
+ ->visit("/builds/{$build->id}/comments")
+ ->waitFor('@comment-text')
+ ->assertPresent('@comment-text')
+ ->assertPresent('@add-comment')
+ ->type('@comment-text', $commentText)
+ ->click('@add-comment')
+ ->waitForText($commentText)
+ ->assertSee($this->user->firstname)
+ ->assertSee($this->user->lastname)
+ ;
+ });
+ }
+
+ public function testNoComments(): void
+ {
+ /** @var Build $build */
+ $build = $this->project->builds()->create([
+ 'siteid' => $this->site->id,
+ 'name' => Str::uuid()->toString(),
+ 'uuid' => Str::uuid()->toString(),
+ ]);
+
+ $this->browse(function (Browser $browser) use ($build): void {
+ $browser->visit("/builds/{$build->id}/comments")
+ ->waitFor('@no-comments-message')
+ ->assertSee('No comments yet.')
+ ->assertMissing('@comments-list');
+ });
+ }
+}
diff --git a/tests/Browser/Pages/BuildSidebarComponentTest.php b/tests/Browser/Pages/BuildSidebarComponentTest.php
index 55f3728ae2..28823bafec 100644
--- a/tests/Browser/Pages/BuildSidebarComponentTest.php
+++ b/tests/Browser/Pages/BuildSidebarComponentTest.php
@@ -14,21 +14,25 @@
use App\Models\Site;
use App\Models\SiteInformation;
use App\Models\UploadFile;
+use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Laravel\Dusk\Browser;
use Tests\BrowserTestCase;
use Tests\Traits\CreatesProjects;
use Tests\Traits\CreatesSites;
+use Tests\Traits\CreatesUsers;
class BuildSidebarComponentTest extends BrowserTestCase
{
use CreatesProjects;
use CreatesSites;
+ use CreatesUsers;
use UpdatesSiteInformation;
private Project $project;
private Site $site;
+ private User $user;
public function setUp(): void
{
@@ -38,12 +42,15 @@ public function setUp(): void
$this->site = $this->makeSite();
$this->updateSiteInfoIfChanged($this->site, new SiteInformation([]));
+
+ $this->user = $this->makeNormalUser();
}
public function tearDown(): void
{
$this->project->delete();
$this->site->delete();
+ $this->user->delete();
parent::tearDown();
}
@@ -76,6 +83,29 @@ public function testSummaryItem(): void
});
}
+ public function testCommentsItem(): void
+ {
+ /** @var Build $build */
+ $build = $this->project->builds()->create([
+ 'siteid' => $this->site->id,
+ 'name' => Str::uuid()->toString(),
+ 'uuid' => Str::uuid()->toString(),
+ ]);
+
+ $this->browse(function (Browser $browser) use ($build): void {
+ $this->assertNotDisabled($browser, "/builds/{$build->id}", '@sidebar-comments', "/builds/{$build->id}/comments");
+
+ $build->comments()->create([
+ 'userid' => $this->user->id,
+ 'text' => 'test comment',
+ ]);
+
+ $browser->visit("/builds/{$build->id}")
+ ->waitFor('@sidebar-loaded')
+ ->assertSeeIn('@sidebar-comments', '1');
+ });
+ }
+
public function testUpdateItem(): void
{
/** @var Build $build */
diff --git a/tests/Browser/Pages/BuildSummaryPageTest.php b/tests/Browser/Pages/BuildSummaryPageTest.php
index a950835b45..a81d8e809f 100644
--- a/tests/Browser/Pages/BuildSummaryPageTest.php
+++ b/tests/Browser/Pages/BuildSummaryPageTest.php
@@ -4,28 +4,23 @@
use App\Http\Submission\Traits\UpdatesSiteInformation;
use App\Models\Build;
-use App\Models\Comment;
use App\Models\Project;
use App\Models\Site;
use App\Models\SiteInformation;
-use App\Models\User;
use Illuminate\Support\Str;
use Laravel\Dusk\Browser;
use Tests\BrowserTestCase;
use Tests\Traits\CreatesProjects;
use Tests\Traits\CreatesSites;
-use Tests\Traits\CreatesUsers;
class BuildSummaryPageTest extends BrowserTestCase
{
use CreatesProjects;
use CreatesSites;
- use CreatesUsers;
use UpdatesSiteInformation;
private Project $project;
private Site $site;
- private User $user;
public function setUp(): void
{
@@ -33,8 +28,6 @@ public function setUp(): void
$this->project = $this->makePublicProject();
- $this->user = $this->makeNormalUser();
-
$this->site = $this->makeSite();
$this->updateSiteInfoIfChanged($this->site, new SiteInformation([]));
}
@@ -90,27 +83,4 @@ public function testShowsHistoryLink(): void
;
});
}
-
- public function testShowsComments(): void
- {
- /** @var Build $build */
- $build = $this->project->builds()->create([
- 'siteid' => $this->site->id,
- 'name' => Str::uuid()->toString(),
- 'uuid' => Str::uuid()->toString(),
- ]);
-
- /** @var Comment $comment */
- $comment = $build->comments()->save(Comment::factory()->make([
- 'userid' => $this->user->id,
- ]));
-
- $this->browse(function (Browser $browser) use ($comment, $build): void {
- $browser->visit("/builds/{$build->id}")
- ->waitForText($comment->text)
- ->assertSee($this->user->firstname)
- ->assertSee($this->user->lastname)
- ;
- });
- }
}