[v12.0/forgejo] fix: compare week as numbers and not as strings (#8887)

**Backport:** https://codeberg.org/forgejo/forgejo/pulls/8882

The repository contributors graph received the stats for each author for each week, these weeks are stored as unix milis values, `Object.entries` converted these values to strings and `sort()` would thus sort them as strings - this worked without a problem for most repository.

If a repository has commits from before 'Sun Sep  9 03:46:40 AM CEST 2001', it meant that the weeks when those commits were made would be sorted towards the end because "1000000000" > "999999999" (when compared as strings) and would thus be silently cut from the data. This edge-case was seen by the curl repository (https://mastodon.social/@bagder/115018271785548165)

Sort them as numbers to avoid this problem, it being stored as strings is otherwise not a problem.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8887
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
This commit is contained in:
forgejo-backport-action 2025-08-13 23:06:30 +02:00 committed by Beowulf
commit 428edf37fb
3 changed files with 81 additions and 1 deletions

View file

@ -0,0 +1,76 @@
import {flushPromises, mount} from '@vue/test-utils';
import RepoContributors from './RepoContributors.vue';
test('has commits from before 2001', async () => {
vi.spyOn(global, 'fetch').mockResolvedValue({
json: vi.fn().mockResolvedValue({
'daniel@haxx.se': {
name: 'Daniel Stenberg',
total_commits: 13,
weeks: {
1754179200000: {
week: 1754179200000,
additions: 4330,
deletions: 47,
commits: 10,
},
946166400000: {
week: 946166400000,
additions: 37273,
deletions: 0,
commits: 1,
},
},
},
total: {
name: 'Total',
total_commits: 11,
weeks: {
1754179200000: {
week: 1754179200000,
additions: 4330,
deletions: 47,
commits: 10,
},
946166400000: {
week: 946166400000,
additions: 37273,
deletions: 0,
commits: 1,
},
},
},
}),
ok: true,
});
const repoContributorsGraph = mount(RepoContributors, {
global: {
stubs: {
'relative-time': {
template: '<span>relative time</span>',
},
},
},
props: {
repoLink: '',
repoDefaultBranchName: '',
locale: {
filterLabel: '',
contributionType: {
commits: '',
additions: '',
deletions: '',
},
loadingTitle: '',
loadingTitleFailed: '',
loadingInfo: '',
},
},
});
await flushPromises();
expect(repoContributorsGraph.componentVM.xAxisStart).toBe(946166400000);
expect(repoContributorsGraph.componentVM.contributorsStats['daniel@haxx.se'].weeks[0].week).toBe(946166400000);
});

View file

@ -125,7 +125,7 @@ export default {
const data = await response.json();
const {total, ...rest} = data;
// below line might be deleted if we are sure go produces map always sorted by keys
total.weeks = Object.fromEntries(Object.entries(total.weeks).sort());
total.weeks = Object.fromEntries(Object.entries(total.weeks).map((x) => [parseInt(x[0]), x[1]]).sort((a, b) => a[0] - b[0]));
const weekValues = Object.values(total.weeks);
this.xAxisStart = weekValues[0].week;