diff --git a/public/popup.html b/public/popup.html
index ad77867..e5b1515 100644
--- a/public/popup.html
+++ b/public/popup.html
@@ -70,6 +70,17 @@
나의 복습 주기
+
+
+
+
알림 시간
+
+
+
+
+
+
+
diff --git a/src/__tests__/api.test.js b/src/__tests__/api.test.js
index b9f6e55..6b6a0eb 100644
--- a/src/__tests__/api.test.js
+++ b/src/__tests__/api.test.js
@@ -7,7 +7,9 @@ import {
getCycleOptions,
createCustomCycle,
updateCustomCycle,
- deleteCustomCycle
+ deleteCustomCycle,
+ getNotificationTime,
+ updateNotificationTime
} from '../api.js';
import { ERROR_CODES } from '../constants.js';
@@ -222,6 +224,55 @@ describe('api.js', () => {
});
});
+ describe('getNotificationTime', () => {
+ it('식별자를 헤더에 포함하여 알림 시간을 조회한다', async () => {
+ const identifier = 'my-device-id';
+ const mockResponse = { success: true, data: { notificationTime: '09:00:00' } };
+ sendMessageMock.mockResolvedValue(mockResponse);
+
+ const result = await getNotificationTime(identifier);
+
+ expect(sendMessageMock).toHaveBeenCalledWith({
+ type: 'API_REQUEST',
+ request: {
+ endpoint: '/api/v1/members/notification-time',
+ method: 'GET',
+ headers: { 'X-Device-Id': identifier }
+ }
+ });
+ expect(result).toEqual(mockResponse.data);
+ });
+
+ it('알림 시간이 설정되지 않은 경우 null을 반환한다', async () => {
+ const mockResponse = { success: true, data: { notificationTime: null } };
+ sendMessageMock.mockResolvedValue(mockResponse);
+
+ const result = await getNotificationTime('my-device-id');
+
+ expect(result.notificationTime).toBeNull();
+ });
+ });
+
+ describe('updateNotificationTime', () => {
+ it('[hour, minute] 배열로 알림 시간을 업데이트한다', async () => {
+ const identifier = 'my-device-id';
+ const mockResponse = { success: true, data: null };
+ sendMessageMock.mockResolvedValue(mockResponse);
+
+ await updateNotificationTime(identifier, 9, 0);
+
+ expect(sendMessageMock).toHaveBeenCalledWith({
+ type: 'API_REQUEST',
+ request: {
+ endpoint: '/api/v1/members/notification-time',
+ method: 'PATCH',
+ headers: { 'X-Device-Id': identifier },
+ body: { notificationTime: [9, 0] }
+ }
+ });
+ });
+ });
+
describe('Error Handling', () => {
it('API 실패 시 에러를 던진다', async () => {
sendMessageMock.mockResolvedValue({
diff --git a/src/api.js b/src/api.js
index 5660700..ecd7784 100644
--- a/src/api.js
+++ b/src/api.js
@@ -148,3 +148,31 @@ export async function deleteCustomCycle(identifier, id) {
headers: { 'X-Device-Id': identifier }
});
}
+
+/**
+ * 알림 시간 조회
+ * @param {string} identifier - 디바이스 식별자
+ * @returns {Promise