Skip to content

[Feature]: Provide Protondb information on game page #2824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/backend/wiki_game_info/__tests__/wiki_game_info.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { GamesDBInfo } from './../../../common/types'
import { HowLongToBeatEntry } from 'howlongtobeat'
import { AppleGamingWikiInfo, WikiInfo, PCGamingWikiInfo } from 'common/types'
import {
AppleGamingWikiInfo,
WikiInfo,
PCGamingWikiInfo,
ProtonDBCompatibilityInfo
} from 'common/types'
import { wikiGameInfoStore } from '../electronStore'
import { getWikiGameInfo } from '../wiki_game_info'
import * as PCGamingWiki from '../pcgamingwiki/utils'
import * as AppleGamingWiki from '../applegamingwiki/utils'
import * as HowLongToBeat from '../howlongtobeat/utils'
import * as GamesDB from '../gamesdb/utils'
import * as ProtonDB from '../protondb/utils'
import { logError } from '../../logger/logger'

jest.mock('electron-store')
Expand Down Expand Up @@ -34,6 +40,9 @@ describe('getWikiGameInfo', () => {
const mockGamesDB = jest
.spyOn(GamesDB, 'getInfoFromGamesDB')
.mockResolvedValue(testGamesDBInfo)
const mockProtonDB = jest
.spyOn(ProtonDB, 'getInfoFromProtonDB')
.mockResolvedValue(testProtonDBInfo)

wikiGameInfoStore.set('The Witcher 3', testExtraGameInfo)

Expand All @@ -43,6 +52,7 @@ describe('getWikiGameInfo', () => {
expect(mockAppleGamingWiki).not.toBeCalled()
expect(mockHowLongToBeat).not.toBeCalled()
expect(mockGamesDB).not.toBeCalled()
expect(mockProtonDB).not.toBeCalled()
})

test('cached data outdated', async () => {
Expand All @@ -61,6 +71,9 @@ describe('getWikiGameInfo', () => {
const mockGamesDB = jest
.spyOn(GamesDB, 'getInfoFromGamesDB')
.mockResolvedValue(testGamesDBInfo)
const mockProtonDB = jest
.spyOn(ProtonDB, 'getInfoFromProtonDB')
.mockResolvedValue(testProtonDBInfo)

wikiGameInfoStore.set('The Witcher 3', {
...testExtraGameInfo,
Expand All @@ -73,6 +86,7 @@ describe('getWikiGameInfo', () => {
expect(mockAppleGamingWiki).toBeCalled()
expect(mockHowLongToBeat).toBeCalled()
expect(mockGamesDB).toBeCalled()
expect(mockProtonDB).toBeCalled()
})

test('catches throws', async () => {
Expand Down Expand Up @@ -136,10 +150,15 @@ const testGamesDBInfo = {
steamID: '123'
} as GamesDBInfo

const testProtonDBInfo = {
level: 'platinum'
} as ProtonDBCompatibilityInfo

const testExtraGameInfo = {
timestampLastFetch: currentTime.toString(),
pcgamingwiki: testPCGamingWikiInfo,
applegamingwiki: testAppleGamingWikiInfo,
howlongtobeat: testHowLongToBeat,
gamesdb: testGamesDBInfo
gamesdb: testGamesDBInfo,
protondb: testProtonDBInfo
} as WikiInfo
44 changes: 44 additions & 0 deletions src/backend/wiki_game_info/protondb/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { logError } from 'backend/logger/logger'
import { getInfoFromProtonDB } from '../utils'
import axios, { AxiosError } from 'axios'

jest.mock('backend/logger/logfile')
jest.mock('backend/logger/logger')

describe('getInfoFromProtonDB', () => {
test('fetches successfully via steamid', async () => {
const mockAxios = jest.spyOn(axios, 'get').mockResolvedValue({
data: { tier: 'gold' }
})

const result = await getInfoFromProtonDB('1234')
expect(result).toStrictEqual(testProtonDBInfo)
expect(mockAxios).toBeCalled()
})

test('does not find game', async () => {
const mockAxios = jest
.spyOn(axios, 'get')
.mockRejectedValue(<AxiosError>new Error('not found'))

const result = await getInfoFromProtonDB('1234')
expect(result).toBeNull()
expect(mockAxios).toBeCalled()
expect(logError).toBeCalledWith(
['Was not able to get ProtonDB data for 1234', undefined],
'ExtraGameInfo'
)
})

test('no SteamID', async () => {
const mockAxios = jest.spyOn(axios, 'get')

const result = await getInfoFromProtonDB('')
expect(result).toBeNull()
expect(mockAxios).not.toBeCalled()
})
})

const testProtonDBInfo = {
level: 'gold'
}
35 changes: 35 additions & 0 deletions src/backend/wiki_game_info/protondb/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ProtonDBInfo, ProtonDBCompatibilityInfo } from 'common/types'
import axios, { AxiosError } from 'axios'
import { logDebug, logError, LogPrefix } from 'backend/logger/logger'

export async function getInfoFromProtonDB(
steamID: string
): Promise<ProtonDBCompatibilityInfo | null> {
if (steamID === '') {
logDebug('No SteamID, not getting ProtonDB info')
return null
}
const url = `https://www.protondb.com/api/v1/reports/summaries/${steamID}.json`

const response = await axios
.get<ProtonDBInfo>(url, { headers: {} })
.catch((error: AxiosError) => {
logError(
[
`Was not able to get ProtonDB data for ${steamID}`,
error.response?.data.error_description
],
LogPrefix.ExtraGameInfo
)
return null
})

if (!response) {
logDebug('No response when getting ProtonDB info')
return null
}
const resp_str = JSON.stringify(response.data)
logDebug(`ProtonDB data for ${steamID} ${resp_str}`)

return { level: response.data.tier }
}
7 changes: 6 additions & 1 deletion src/backend/wiki_game_info/wiki_game_info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getInfoFromGamesDB } from 'backend/wiki_game_info/gamesdb/utils'
import { getInfoFromProtonDB } from 'backend/wiki_game_info/protondb/utils'
import { wikiGameInfoStore } from './electronStore'
import { removeSpecialcharacters } from '../utils'
import { Runner, WikiInfo } from 'common/types'
Expand Down Expand Up @@ -48,12 +49,16 @@ export async function getWikiGameInfo(
isMac ? getInfoFromAppleGamingWiki(title) : null
])

const protondb = await getInfoFromProtonDB(
gamesdb?.steamID ? gamesdb.steamID : ''
)
const wikiGameInfo = {
timestampLastFetch: Date(),
pcgamingwiki,
applegamingwiki,
howlongtobeat,
gamesdb
gamesdb,
protondb
}

wikiGameInfoStore.set(title, wikiGameInfo)
Expand Down
13 changes: 13 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,25 @@ export interface GamesDBInfo {
steamID: string
}

export interface ProtonDBCompatibilityInfo {
level: string
}
export interface ProtonDBInfo {
bestReportedTier: string
confidence: string
score: number
tier: string
total: number
trendingTier: string
}

export interface WikiInfo {
timestampLastFetch: string
pcgamingwiki: PCGamingWikiInfo | null
applegamingwiki: AppleGamingWikiInfo | null
howlongtobeat: HowLongToBeatEntry | null
gamesdb: GamesDBInfo | null
protondb: ProtonDBCompatibilityInfo | null
}

/**
Expand Down