Skip to content

Commit 6a1e96e

Browse files
committed
test(acceptance): add language switch test on leaderboard page
Refactor leaderboard page test helper by extracting language dropdown into its own component and enhancing entries collection to include username text. Add a new acceptance test to verify that users can switch between Rust and Python leaderboards, ensuring the URL updates correctly and leaderboard entries reflect the selected language. This improves test coverage for multi-language support and ensures UI correctness when changing the leaderboard language.
1 parent a83a706 commit 6a1e96e

File tree

5 files changed

+77
-16
lines changed

5 files changed

+77
-16
lines changed

app/components/leaderboard-page/entries-table/row.hbs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212
<AvatarImage @user={{@entry.user}} class="h-6 w-6 rounded-full border border-gray-300" />
1313
</div>
1414
<div class="text-xs font-mono max-w-[12ch] sm:max-w-[16ch] truncate {{if this.isCurrentUser 'text-teal-600' 'text-gray-600'}}">
15-
<a href={{@entry.user.codecraftersProfileUrl}} target="_blank" class="hover:underline hover:text-gray-800" rel="noopener noreferrer">
15+
<a
16+
href={{@entry.user.codecraftersProfileUrl}}
17+
target="_blank"
18+
class="hover:underline hover:text-gray-800"
19+
rel="noopener noreferrer"
20+
data-test-username
21+
>
1622
{{@entry.user.username}}
1723
</a>
1824
</div>

app/components/leaderboard-page/header.hbs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
@requestedLanguage={{@selectedLanguage}}
1818
@selectedLanguage={{@selectedLanguage}}
1919
@shouldShowAllLanguagesOption={{false}}
20-
@onRequestedLanguageChange={{(noop)}}
21-
@onDidInsertDropdown={{(noop)}}
20+
@onRequestedLanguageChange={{this.handleRequestedLanguageChange}}
2221
/>
2322
</div>

app/components/leaderboard-page/header.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import Component from '@glimmer/component';
2+
import { action } from '@ember/object';
23
import { inject as service } from '@ember/service';
3-
import type Store from '@ember-data/store';
44
import type LanguageModel from 'codecrafters-frontend/models/language';
5+
import type RouterService from '@ember/routing/router-service';
6+
import type Store from '@ember-data/store';
57

68
interface Signature {
79
Element: HTMLDivElement;
@@ -12,6 +14,7 @@ interface Signature {
1214
}
1315

1416
export default class LeaderboardPageHeader extends Component<Signature> {
17+
@service declare router: RouterService;
1518
@service declare store: Store;
1619

1720
get sortedLanguagesForDropdown(): LanguageModel[] {
@@ -20,6 +23,11 @@ export default class LeaderboardPageHeader extends Component<Signature> {
2023
.sortBy('sortPositionForTrack')
2124
.filter((language) => language.stagesCount > 0);
2225
}
26+
27+
@action
28+
handleRequestedLanguageChange(language: LanguageModel) {
29+
this.router.transitionTo('leaderboard', language.slug);
30+
}
2331
}
2432

2533
declare module '@glint/environment-ember-loose/registry' {

tests/acceptance/leaderboard-page/view-test.js

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { currentURL } from '@ember/test-helpers';
2-
import testScenario from 'codecrafters-frontend/mirage/scenarios/test';
3-
import { setupApplicationTest } from 'codecrafters-frontend/tests/helpers';
41
import leaderboardPage from 'codecrafters-frontend/tests/pages/leaderboard-page';
5-
import { signInAsStaff } from 'codecrafters-frontend/tests/support/authentication-helpers';
2+
import percySnapshot from '@percy/ember';
3+
import testScenario from 'codecrafters-frontend/mirage/scenarios/test';
4+
import { currentURL } from '@ember/test-helpers';
5+
import { module, test } from 'qunit';
66
import { setupAnimationTest } from 'ember-animated/test-support';
7+
import { setupApplicationTest } from 'codecrafters-frontend/tests/helpers';
78
import { setupWindowMock } from 'ember-window-mock/test-support';
8-
import { module, test } from 'qunit';
9-
import percySnapshot from '@percy/ember';
9+
import { signInAsStaff } from 'codecrafters-frontend/tests/support/authentication-helpers';
1010

1111
module('Acceptance | leaderboard-page | view', function (hooks) {
1212
setupApplicationTest(hooks);
@@ -74,7 +74,55 @@ module('Acceptance | leaderboard-page | view', function (hooks) {
7474
await percySnapshot('Leaderboard Page');
7575
});
7676

77-
// Test that one can switch languages
77+
test('can switch languages', async function (assert) {
78+
signInAsStaff(this.owner, this.server);
79+
80+
// Create leaderboards for multiple languages
81+
const rustLanguage = this.server.schema.languages.all().models.find((language) => language.slug === 'rust');
82+
const pythonLanguage = this.server.schema.languages.all().models.find((language) => language.slug === 'python');
83+
84+
// Create sample data for both languages
85+
const sampleUserData = [
86+
{ username: 'rust-user-1', score: 1000, leaderboard: rustLanguage.leaderboard },
87+
{ username: 'rust-user-2', score: 800, leaderboard: rustLanguage.leaderboard },
88+
{ username: 'python-user-1', score: 900, leaderboard: pythonLanguage.leaderboard },
89+
{ username: 'python-user-2', score: 700, leaderboard: pythonLanguage.leaderboard },
90+
];
91+
92+
for (const sampleUserDatum of sampleUserData) {
93+
let user = this.server.schema.users.all().models.find((user) => user.username === sampleUserDatum.username);
94+
95+
user ||= this.server.create('user', {
96+
username: sampleUserDatum.username,
97+
avatarUrl: `https://github.com/${sampleUserDatum.username}.png`,
98+
});
99+
100+
// Create entries for both languages
101+
this.server.create('leaderboard-entry', {
102+
leaderboard: sampleUserDatum.leaderboard,
103+
user: user,
104+
score: sampleUserDatum.score,
105+
scoreUpdatesCount: Math.floor(sampleUserDatum.score / 10),
106+
relatedCourseSlugs: ['redis', 'shell'],
107+
});
108+
}
109+
110+
// Start on Rust leaderboard
111+
await leaderboardPage.visit({ language_slug: 'rust' });
112+
assert.strictEqual(currentURL(), '/leaderboards/rust');
113+
assert.strictEqual(leaderboardPage.entriesTable.entries.length, 2, '2 Rust entries should be shown');
114+
assert.strictEqual(leaderboardPage.entriesTable.entries[0].username, 'rust-user-1', 'first entry should be rust-user-1');
115+
assert.strictEqual(leaderboardPage.entriesTable.entries[1].username, 'rust-user-2', 'second entry should be rust-user-2');
116+
117+
// Switch to Python leaderboard
118+
await leaderboardPage.languageDropdown.toggle();
119+
await leaderboardPage.languageDropdown.clickOnLink('Python');
120+
assert.strictEqual(currentURL(), '/leaderboards/python', 'URL should change to Python leaderboard');
121+
assert.strictEqual(leaderboardPage.entriesTable.entries.length, 2, '2 Python entries should be shown');
122+
assert.strictEqual(leaderboardPage.entriesTable.entries[0].username, 'python-user-1', 'first entry should be python-user-1');
123+
assert.strictEqual(leaderboardPage.entriesTable.entries[1].username, 'python-user-2', 'second entry should be python-user-2');
124+
});
125+
78126
// Test that surrounding entries are shown if user is not within top 10
79127
// Test that surrounding entries are not shown if user is within top 10
80128
});

tests/pages/leaderboard-page.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { collection, text, visitable } from 'ember-cli-page-object';
22
import createPage from 'codecrafters-frontend/tests/support/create-page';
3+
import LanguageDropdown from './components/language-dropdown';
34

45
export default createPage({
56
description: text('[data-test-leaderboard-description]'),
67

78
entriesTable: {
8-
entries: collection('[data-test-leaderboard-entry-row]'),
9-
},
10-
11-
languageDropdown: {
12-
scope: '[data-test-language-dropdown]',
9+
entries: collection('[data-test-leaderboard-entry-row]', {
10+
username: text('[data-test-username]'),
11+
}),
1312
},
1413

14+
languageDropdown: LanguageDropdown,
1515
title: text('[data-test-leaderboard-title]'),
1616
visit: visitable('/leaderboards/:language_slug'),
1717
});

0 commit comments

Comments
 (0)