Skip to content

Commit

Permalink
278 show track when selecting future race under results (#280)
Browse files Browse the repository at this point in the history
* Results > Showing track if race has not been raced
  • Loading branch information
marcokreeft87 authored Aug 8, 2023
1 parent b864f82 commit 586ac38
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 103 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ The following texts can be translated or altered.
| results | selectseason | 'Select season' |
| results | selectrace | 'Select race' |
| results | noresults | 'Please select a race thats already been run' |
| results | nosprint | 'No sprint race results available.' |
| countdown | days | 'd' |
| countdown | hours | 'h' |
| countdown | minutes | 'm' |
Expand Down
76 changes: 31 additions & 45 deletions formulaone-card.js

Large diffs are not rendered by default.

Binary file modified formulaone-card.js.gz
Binary file not shown.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "formulaone-card",
"version": "1.8.5",
"version": "1.8.6",
"description": "Frontend card for Home Assistant to display Formula One data",
"main": "index.js",
"scripts": {
Expand Down
97 changes: 47 additions & 50 deletions src/cards/results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ export default class Results extends BaseCard {
'seasonheader' : 'Season',
'selectseason' : 'Select season',
'selectrace' : 'Select race',
'noresults' : 'Please select a race thats already been run.',
'nosprint' : 'No sprint race results available.',
'noresults' : 'Please select a race thats already been run.',
'q1' : 'Q1',
'q2' : 'Q2',
'q3' : 'Q3',
Expand Down Expand Up @@ -78,11 +77,7 @@ export default class Results extends BaseCard {
${reduceArray(selectedRace.SprintResults, this.config.row_limit).map(result => this.renderResultRow(result, false))}
</tbody>
</table>`
: html`<table class="nopadding">
<tr>
<td class="text-center">${this.translation('nosprint')}</td>
</tr>
</table>`;
: null;
}

renderQualifying(selectedRace: Race): HTMLTemplateResult {
Expand All @@ -102,16 +97,12 @@ export default class Results extends BaseCard {
${reduceArray(selectedRace.QualifyingResults, this.config.row_limit).map(result => this.renderQualifyingResultRow(result))}
</tbody>
</table>`
: html`<table class="nopadding">
<tr>
<td>${this.translation('noresults')}</td>
</tr>
</table>`;
: null;
}

renderResults(selectedRace: Race): HTMLTemplateResult {
const fastest = selectedRace?.Results?.filter((result) => result.FastestLap?.rank === '1')[0];
return selectedRace ?
return selectedRace?.Results ?
html`<table class="nopadding">
<thead>
<tr>
Expand All @@ -132,11 +123,7 @@ export default class Results extends BaseCard {
<td colspan="6" class="text-right"><small>* Fastest lap: ${fastest.FastestLap.Time.time}</small></td>
</tfoot>` : ''}
</table>`
: html`<table class="nopadding">
<tr>
<td>${this.translation('noresults')}</td>
</tr>
</table>`;
: null;
}

renderResultRow(result: Result, fastest: boolean): HTMLTemplateResult {
Expand Down Expand Up @@ -221,38 +208,42 @@ export default class Results extends BaseCard {
</td>
</tr>
</table>
${this.renderTabsHtml(tabs, selectedTabIndex, selectedRace)}`;

${selectedRace
}

renderTabsHtml = (tabs: FormulaOneCardTab[], selectedTabIndex: number, selectedRace?: Race): HTMLTemplateResult => {
return selectedRace
? html`<table>
<tr><td colspan="2">${this.renderHeader(selectedRace)}</td></tr>
<tr class="transparent">
<td colspan="2">
<mwc-tab-bar
@MDCTabBar:activated=${(ev: mwcTabBarEvent) =>
(this.setSelectedTabIndex(ev.detail.index))}
>
${tabs.filter(tab => !tab.hide).map(
(tab) => html`
<mwc-tab
?hasImageIcon=${tab.icon}
><ha-icon
slot="icon"
icon="${tab.icon}"
></ha-icon>
</mwc-tab>
`,
)}
</mwc-tab-bar>
<section>
<article>
${tabs.filter(tab => !tab.hide).find((_, index) => index == selectedTabIndex).content}
</article>
</section>
</td>
</tr>
${tabs.filter(tab => tab.content).length > 0 ?
html`<tr class="transparent">
<td colspan="2">
<mwc-tab-bar
@MDCTabBar:activated=${(ev: mwcTabBarEvent) =>
(this.setSelectedTabIndex(ev.detail.index))}
>
${tabs.filter(tab => !tab.hide).map(
(tab) => html`
<mwc-tab
?hasImageIcon=${tab.icon}
><ha-icon
slot="icon"
icon="${tab.icon}"
></ha-icon>
</mwc-tab>
`,
)}
</mwc-tab-bar>
<section>
<article>
${tabs.filter(tab => !tab.hide).find((_, index) => index == selectedTabIndex).content}
</article>
</section>
</td>
</tr>` : html`<tr><td colspan="2">${this.translation('noresults')}</td></tr>`}
</table>`
: html``}
`;
: html``;
}

setSelectedRace(ev: SelectChangeEvent) {
Expand All @@ -265,15 +256,21 @@ export default class Results extends BaseCard {

Promise.all([this.client.GetResults(selectedSeason, round),
this.client.GetQualifyingResults(selectedSeason, round),
this.client.GetSprintResults(selectedSeason, round)])
.then(([results, qualifyingResults, sprintResults]) => {
this.client.GetSprintResults(selectedSeason, round),
this.client.GetSchedule(selectedSeason)])
.then(([results, qualifyingResults, sprintResults, schedule]) => {

const race = results.Races[0];
let race = results.Races[0];
/* istanbul ignore next */
if(race) {
race.QualifyingResults = qualifyingResults.Races[0].QualifyingResults;
/* istanbul ignore next */
race.SprintResults = sprintResults?.Races[0]?.SprintResults
properties.selectedSeason = race.season;
properties.selectedSeason = race.season;
/* istanbul ignore next */
} else {
/* istanbul ignore next */
race = schedule.filter(item => parseInt(item.round) == round)[0];
}

properties.selectedRace = race;
Expand Down
60 changes: 56 additions & 4 deletions tests/cards/results.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import FormulaOneCard from "../../src";
import ErgastClient from "../../src/api/ergast-client";
import { FastestLap, Mrdata, QualifyingResult, Race, Result, Root } from "../../src/api/f1-models";
import Results from "../../src/cards/results";
import { CardProperties, FormulaOneCardConfig, mwcTabBarEvent } from "../../src/types/formulaone-card-types";
import { CardProperties, FormulaOneCardConfig, FormulaOneCardTab, mwcTabBarEvent } from "../../src/types/formulaone-card-types";
import { getRenderString, getRenderStringAsync, getRenderStringAsyncIndex } from "../utils";
import { HTMLTemplateResult } from "lit";
import { HTMLTemplateResult, html } from "lit";
import RestCountryClient from "../../src/api/restcountry-client";
import { Country } from "../../src/types/rest-country-types";
import ImageClient from "../../src/api/image-client";
Expand Down Expand Up @@ -105,7 +105,7 @@ describe('Testing results file', () => {

// Assert
// eslint-disable-next-line @typescript-eslint/ban-types
const func = (result.values[7] as HTMLTemplateResult).values[1] as Function;
const func = ((result.values[7] as HTMLTemplateResult).values[1] as HTMLTemplateResult).values[0] as Function;
func({ detail: { index: 23 } } as mwcTabBarEvent);

const cardValues = card.parent.properties.get('cardValues') as CardProperties;
Expand Down Expand Up @@ -421,7 +421,7 @@ describe('Testing results file', () => {
expect(fetchMock).toHaveBeenCalledWith("https://ergast.com/api/f1/2022/6/results.json", {"headers": {"Accept": "application/json"}});
expect(fetchMock).toHaveBeenCalledWith("https://ergast.com/api/f1/2022/6/qualifying.json", {"headers": {"Accept": "application/json"}});
expect(fetchMock).toHaveBeenCalledWith("https://ergast.com/api/f1/2022/6/sprint.json", {"headers": {"Accept": "application/json"}});
}),
}),
test('Calling setSelectedRace with selectedSeason undefined no results', async () => {
// Arrange
parent.properties.set('cardValues', { selectedSeason: '2022', selectedRace: undefined });
Expand Down Expand Up @@ -496,6 +496,58 @@ describe('Testing results file', () => {
expect(tabs[0].title).toBe('Qualifying');
expect(tabs[1].title).toBe('Sprint');
expect(tabs[2].title).toBe('Results');
}),
test('Calling renderTabsHtml with race, tabs and selected index should return expected html', async () => {
// Arrange
const race = resultData.RaceTable.Races[0] as Race;

const card = new Results(parent);
const tabs: FormulaOneCardTab[] = [
{ title: 'Qualifying', content: html`Qualifying`, icon: 'speed' },
{ title: 'Sprint', content: html`Sprint`, icon: 'speed' },
{ title: 'Results', content: html`Results`, icon: 'speed' }
];

// Act
const result = card.renderTabsHtml(tabs, 1, race);
const htmlResult = await getRenderString(result);

// Assert
expect(htmlResult).toBe('<table> <tr><td colspan="2"><h2 class=""><img height="25" src="https://flagcdn.com/w320/sg.png">&nbsp; 1 : Singapore Grand Prix</h2> <img width="100%" src="https://www.formula1.com/content/dam/fom-website/2018-redesign-assets/Circuit%20maps%2016x9/Singapore_Circuit.png.transform/7col/image.png" @action=_handleAction .actionHandler= class=" clickable" /><br></td></tr> <tr class="transparent"> <td colspan="2"> <mwc-tab-bar @MDCTabBar:activated= > <mwc-tab ?hasImageIcon=speed ><ha-icon slot="icon" icon="speed" ></ha-icon> </mwc-tab> <mwc-tab ?hasImageIcon=speed ><ha-icon slot="icon" icon="speed" ></ha-icon> </mwc-tab> <mwc-tab ?hasImageIcon=speed ><ha-icon slot="icon" icon="speed" ></ha-icon> </mwc-tab> </mwc-tab-bar> <section> <article> Sprint </article> </section> </td> </tr> </table>');
}),
test('Calling renderTabsHtml with race, tabs and selected index should return expected html', async () => {
// Arrange
const race = resultData.RaceTable.Races[0] as Race;

const card = new Results(parent);
const tabs: FormulaOneCardTab[] = [
{ title: 'Qualifying', content: null as unknown as HTMLTemplateResult, icon: 'speed' },
{ title: 'Sprint', content: null as unknown as HTMLTemplateResult, icon: 'speed' },
{ title: 'Results', content: null as unknown as HTMLTemplateResult, icon: 'speed' }
];

// Act
const result = card.renderTabsHtml(tabs, 1, race);
const htmlResult = await getRenderString(result);

// Assert
expect(htmlResult).toBe('<table> <tr><td colspan="2"><h2 class=""><img height="25" src="https://flagcdn.com/w320/sg.png">&nbsp; 1 : Singapore Grand Prix</h2> <img width="100%" src="https://www.formula1.com/content/dam/fom-website/2018-redesign-assets/Circuit%20maps%2016x9/Singapore_Circuit.png.transform/7col/image.png" @action=_handleAction .actionHandler= class=" clickable" /><br></td></tr> <tr><td colspan="2">Please select a race thats already been run.</td></tr> </table>');
}),
test('Calling renderTabsHtml with race undefined, tabs and selected index should return expected html', async () => {
// Arrange
const card = new Results(parent);
const tabs: FormulaOneCardTab[] = [
{ title: 'Qualifying', content: html`Qualifying`, icon: 'speed' },
{ title: 'Sprint', content: html`Sprint`, icon: 'speed' },
{ title: 'Results', content: html`Results`, icon: 'speed' }
];

// Act
const result = card.renderTabsHtml(tabs, 1, undefined);
const htmlResult = await getRenderString(result);

// Assert
expect(htmlResult).toBe('');
})

function setFetchMock() {
Expand Down
Loading

0 comments on commit 586ac38

Please sign in to comment.