diff --git a/__tests__/current-alias-redirects.ts b/__tests__/current-alias-redirects.ts index bc13b27d..6f52b3b8 100644 --- a/__tests__/current-alias-redirects.ts +++ b/__tests__/current-alias-redirects.ts @@ -74,41 +74,31 @@ describe('redirects for course pages', () => { id: 42, __typename: 'Course', alias: '/math/42/a-course', - currentRevision: { - content: JSON.stringify({ - state: { - pages: [ - { id: '527bcd55-977c-489d-a3c8-9fd0feaf51a6', title: 'Foo' }, - { id: 'a47077ca-a9f9-4ab9-bf22-6c26fb3490d8', title: 'Bar' }, - ], - }, - }), - }, }) }) test('redirect first course page to course alias', async () => { const response = await localTestEnvironment().fetch({ subdomain: 'en', - pathname: '/math/42/527bcd55/xyz', + pathname: '/math/42/527bc/foo', }) const target = env.createUrl({ subdomain: 'en', - pathname: '/math/42/a-course', + pathname: '/math/42/a-course#527bc', }) expectToBeRedirectTo(response, target, 301) }) - test('redirect course page url when title was changed', async () => { + test('redirect any course page url to course alias, even with differen title', async () => { const response = await localTestEnvironment().fetch({ subdomain: 'en', - pathname: '/math/42/a47077ca/xyz', + pathname: '/math/42/a4707/xyz', }) const target = env.createUrl({ subdomain: 'en', - pathname: '/math/42/a47077ca/bar', + pathname: '/math/42/a-course#a4707', }) expectToBeRedirectTo(response, target, 301) }) diff --git a/src/current-alias-redirects.ts b/src/current-alias-redirects.ts index 1df83b6c..862e3c6b 100644 --- a/src/current-alias-redirects.ts +++ b/src/current-alias-redirects.ts @@ -51,13 +51,6 @@ const ApiResult = t.type({ const CourseResult = t.type({ id: t.number, alias: t.string, - currentRevision: t.type({ content: t.string }), -}) - -const CourseContent = t.type({ - state: t.type({ - pages: t.array(t.type({ title: t.string, id: t.string })), - }), }) async function getPathInfo( @@ -94,9 +87,6 @@ async function getPathInfo( ... on Course { id alias - currentRevision { - content - } } ... on Comment { id @@ -136,53 +126,29 @@ async function getPathInfo( const isTrashedComment = uuid.__typename === 'Comment' && uuid.trashed let currentPath: string = '' + let hash: string = '' if (coursePageId !== null) { if (!CourseResult.is(uuid)) return null - try { - const courseContent = JSON.parse(uuid.currentRevision.content) as unknown - - if (!CourseContent.is(courseContent)) return null - - if (courseContent.state.pages.at(0)?.id?.startsWith(coursePageId)) { - currentPath = uuid.alias - } else { - const coursePage = courseContent.state.pages.find((page) => - page.id.startsWith(coursePageId), - ) - - if (coursePage === undefined) { - // This case should never happen => return course alias as a fallback - currentPath = uuid.alias - } else { - const subject = uuid.alias.split('/').at(1) ?? 'serlo' - const slugTitle = toSlug(coursePage.title) - const shortPageId = coursePage.id.split('-').at(0) - if (!shortPageId) { - currentPath = uuid.alias - } else { - currentPath = `/${subject}/${uuid.id}/${shortPageId}/${slugTitle}` - } - } - } - } catch { - return null - } + currentPath = uuid.alias + hash = `#${coursePageId}` } else { currentPath = isTrashedComment ? `error/deleted/${uuid.__typename}` : uuid.legacyObject !== undefined ? uuid.legacyObject.alias : (uuid.alias ?? path) + + if (uuid.legacyObject !== undefined && !isTrashedComment) { + hash = `#comment-${uuid.id ?? 0}` + } } const result = { currentPath, instance: uuid.instance, - ...(uuid.legacyObject !== undefined && !isTrashedComment - ? { hash: `#comment-${uuid.id ?? 0}` } - : {}), + ...(hash ? { hash } : {}), } await env.PATH_INFO_KV.put(cacheKey, JSON.stringify(result), { @@ -199,25 +165,3 @@ async function getPathInfo( function gql(strings: TemplateStringsArray): string { return strings[0] } - -// Copied from https://github.com/serlo/api.serlo.org/blob/ce94045b513e59da1ddd191b498fe01f6ff6aa0a/packages/server/src/schema/uuid/abstract-uuid/resolvers.ts#L685-L703 -// Try to keep both functions in sync -function toSlug(name: string) { - return name - .toLowerCase() - .replace(/ä/g, 'ae') - .replace(/ö/g, 'oe') - .replace(/ü/g, 'ue') - .replace(/ß/g, 'ss') - .replace(/á/g, 'a') - .replace(/é/g, 'e') - .replace(/í/g, 'i') - .replace(/ó/g, 'o') - .replace(/ú/g, 'u') - .replace(/ñ/g, 'n') - .replace(/ /g, '-') // replace spaces with hyphens - .replace(/[^\w-]+/g, '') // remove all non-word chars including _ - .replace(/--+/g, '-') // replace multiple hyphens - .replace(/^-+/, '') // trim starting hyphen - .replace(/-+$/, '') // trim end hyphen -}