Skip to content

Commit 3f1f0c8

Browse files
authored
Merge pull request #3078 from codecrafters-io/test-add-language-switch-leaderboard
test(acceptance): add language switch test on leaderboard page
2 parents 56a2814 + 6a1e96e commit 3f1f0c8

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)