Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ jobs:
CI: true
NEXT_TELEMETRY_DISABLED: 1
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
CYPRESS_NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
CYPRESS_TEST_USER_ID: ${{ secrets.CYPRESS_TEST_USER_ID }}
CYPRESS_TEST_USER_PW: ${{ secrets.CYPRESS_TEST_USER_PW }}
CYPRESS_TEST_USER_NUMBER: ${{ secrets.CYPRESS_TEST_USER_NUMBER }}
CYPRESS_TEST_UNIVERSITY_NAME: ${{ secrets.TEST_UNIVERSITY_NAME }}

- name: "========== 🧪 AllClass E2E • END =========="
if: always()
Expand Down
1 change: 1 addition & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const geistMono = Geist_Mono({
});

export const metadata: Metadata = {
metadataBase: new URL('https://allclass.vercel.app'),
title: {
default: 'AllClass - 부산소속 대학교 강의정보 플랫폼',
template: '%s | AllClass',
Expand Down
34 changes: 7 additions & 27 deletions app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,24 @@
import { MetadataRoute } from 'next';
import { universityNames } from '@/constants';
import { getLectureListStatic } from '@/lib/lecture';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = 'https://all-class.vercel.app';
export default function sitemap(): MetadataRoute.Sitemap {
const baseUrl = 'https://allclass.vercel.app';

const staticPages = [
const staticPages: MetadataRoute.Sitemap = [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'daily' as const,
changeFrequency: 'daily',
priority: 1,
},
];

const universityPages = universityNames.map((universityName) => ({
const universityPages: MetadataRoute.Sitemap = universityNames.map((universityName) => ({
url: `${baseUrl}/${encodeURIComponent(universityName)}`,
lastModified: new Date(),
changeFrequency: 'daily' as const,
changeFrequency: 'daily',
priority: 0.8,
}));

const lecturePages: MetadataRoute.Sitemap = [];

for (const universityName of universityNames) {
try {
const lectures = await getLectureListStatic(universityName);
if (lectures.success && lectures.lectures) {
const pages = lectures.lectures.map((lecture) => ({
url: `${baseUrl}/${encodeURIComponent(universityName)}/${lecture.lectureId}`,
lastModified: new Date(),
changeFrequency: 'weekly' as const,
priority: 0.7,
}));
lecturePages.push(...pages);
}
} catch (error) {
console.error(`Error generating sitemap for ${universityName}:`, error);
}
}

return [...staticPages, ...universityPages, ...lecturePages];
return [...staticPages, ...universityPages];
}
16 changes: 16 additions & 0 deletions cypress/e2e/tier1-critical/01-auth-and-review.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@ describe('사용자는 로그인을하고 자신이 들은 강의에 리뷰를
cy.uiLogin();

cy.getMyLectures().then((response) => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
expect(response.status).to.eq(200);

cy.then(() => console.log('getMyLectures response:', response.body));

// eslint-disable-next-line @typescript-eslint/no-unused-expressions
expect(response.body.data).to.not.be.null;

// eslint-disable-next-line @typescript-eslint/no-unused-expressions
expect(response.body.data).to.be.an('array');
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
expect(response.body.data).to.have.length.greaterThan(0);

const enrolledLecture = response.body.data[0];
Expand Down Expand Up @@ -47,6 +57,12 @@ describe('사용자는 로그인을하고 자신이 들은 강의에 리뷰를
cy.uiLogin();

cy.getMyLectures().then((enrolledResponse) => {
cy.then(() => console.log('getMyLectures response:', enrolledResponse.body));
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
expect(enrolledResponse.body.data).to.not.be.null;
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
expect(enrolledResponse.body.data).to.be.an('array');

const enrolledLectures = enrolledResponse.body.data.map(
(lecture: { lectureName: string }) => lecture.lectureName
);
Expand Down
30 changes: 25 additions & 5 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,32 @@ Cypress.Commands.add('uiLogin', (userId?: string, userPw?: string) => {
});

Cypress.Commands.add('getMyLectures', () => {
const apiUrl = Cypress.env('NEXT_PUBLIC_API_URL') || Cypress.env('CYPRESS_NEXT_PUBLIC_API_URL');
if (!apiUrl) {
throw new Error('NEXT_PUBLIC_API_URL 환경변수가 설정되지 않았습니다');
}

const userNumber = Cypress.env('TEST_USER_NUMBER') || Cypress.env('CYPRESS_TEST_USER_NUMBER');

cy.log(`API URL: ${apiUrl}`);
cy.log(`User Number: ${userNumber}`);

return cy.request({
method: 'GET',
url: `${Cypress.env('NEXT_PUBLIC_API_URL')}/class/me`,
qs: { userNumber: Cypress.env('TEST_USER_NUMBER') },
url: `${apiUrl}/class/me`,
qs: { userNumber },
});
});

Cypress.Commands.add('getUniversityLectures', (universityName: string) => {
const apiUrl = Cypress.env('NEXT_PUBLIC_API_URL') || Cypress.env('CYPRESS_NEXT_PUBLIC_API_URL');
if (!apiUrl) {
throw new Error('NEXT_PUBLIC_API_URL 환경변수가 설정되지 않았습니다');
}

return cy.request({
method: 'GET',
url: `${Cypress.env('NEXT_PUBLIC_API_URL')}/class`,
url: `${apiUrl}/class`,
qs: { university: universityName },
});
});
Expand All @@ -82,7 +97,6 @@ Cypress.Commands.add('getLectureWithReviews', (universityName: string) => {
return cy.getUniversityLectures(universityName).then((response) => {
const lectures = response.body.data as { lectureName: string; lectureId: number }[];

// 각 강의를 순차적으로 확인하여 리뷰가 있는 첫 번째 강의 찾기
let currentIndex = 0;

const checkNextLecture = (): Cypress.Chainable<{ lectureName: string; lectureId: number }> => {
Expand All @@ -92,10 +106,16 @@ Cypress.Commands.add('getLectureWithReviews', (universityName: string) => {

const lecture = lectures[currentIndex];

const apiUrl =
Cypress.env('NEXT_PUBLIC_API_URL') || Cypress.env('CYPRESS_NEXT_PUBLIC_API_URL');
if (!apiUrl) {
throw new Error('NEXT_PUBLIC_API_URL 환경변수가 설정되지 않았습니다');
}

return cy
.request({
method: 'GET',
url: `${Cypress.env('NEXT_PUBLIC_API_URL')}/class`,
url: `${apiUrl}/class`,
qs: {
university: universityName,
lectureId: lecture.lectureId,
Expand Down