From 48548dadc80dd0194827ddd050a50ceba3ac5d4f Mon Sep 17 00:00:00 2001
From: ryan <ryannganga13325@gmail.com>
Date: Tue, 15 Apr 2025 17:04:34 +0300
Subject: [PATCH] test(smart url): add tests for smart url handling

---
 package-lock.json     | 39 ++++++++++++++++++++++++++
 package.json          |  1 +
 test/calendar.test.js | 64 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 71ace9e..6f5b184 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
         "@babel/plugin-transform-modules-commonjs": "^7.25.9",
         "@babel/preset-env": "^7.26.0",
         "@babel/register": "^7.25.9",
+        "axios-mock-adapter": "^2.1.0",
         "babel-jest": "^29.7.0",
         "jest": "^29.7.0",
         "rewire": "^7.0.0"
@@ -2679,6 +2680,20 @@
         "proxy-from-env": "^1.1.0"
       }
     },
+    "node_modules/axios-mock-adapter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-2.1.0.tgz",
+      "integrity": "sha512-AZUe4OjECGCNNssH8SOdtneiQELsqTsat3SQQCWLPjN436/H+L9AjWfV7bF+Zg/YL9cgbhrz5671hoh+Tbn98w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "is-buffer": "^2.0.5"
+      },
+      "peerDependencies": {
+        "axios": ">= 0.17.0"
+      }
+    },
     "node_modules/babel-jest": {
       "version": "29.7.0",
       "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
@@ -4502,6 +4517,30 @@
       "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
+    "node_modules/is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/is-core-module": {
       "version": "2.15.1",
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
diff --git a/package.json b/package.json
index 912361d..5c4dc8b 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
     "@babel/plugin-transform-modules-commonjs": "^7.25.9",
     "@babel/preset-env": "^7.26.0",
     "@babel/register": "^7.25.9",
+    "axios-mock-adapter": "^2.1.0",
     "babel-jest": "^29.7.0",
     "jest": "^29.7.0",
     "rewire": "^7.0.0"
diff --git a/test/calendar.test.js b/test/calendar.test.js
index 79c48a2..45996e5 100644
--- a/test/calendar.test.js
+++ b/test/calendar.test.js
@@ -2,12 +2,15 @@ import request from 'supertest';
 import fs from 'fs';
 import path from 'path';
 import { fileURLToPath } from 'url';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import { fetchCalendarData } from '../src/calendarUtil.js';
 
 // ESM equivalent of __dirname
 const __filename = fileURLToPath(import.meta.url);
 const __dirname = path.dirname(__filename);
 
-const CALENDARS_DIR = path.join(__dirname, 'calendar');
+const CALENDARS_DIR = path.join(process.cwd(), 'calendar');
 const TEST_CALENDARS_DIR = path.join(__dirname, 'test_calendars');
 const EXPECTED_OUTPUTS_DIR = path.join(__dirname, 'expected_outputs');
 
@@ -26,9 +29,8 @@ describe('Calendar Merging API', () => {
         await new Promise(resolve => server.close(resolve));
 
         // Clean up the merged calendars directory after tests
-        fs.rmdirSync(CALENDARS_DIR, { recursive: true });
         if (fs.existsSync(CALENDARS_DIR)) {
-            fs.rmdirSync(CALENDARS_DIR, { recursive: true });
+            fs.rmSync(CALENDARS_DIR, { recursive: true, force: true });
         }
 
         // Optional: Add a delay to ensure all handles are released
@@ -280,4 +282,60 @@ describe('Calendar Merging API', () => {
     expect(actualOutput).toBe(expectedOutput);
     });
 
+    describe('Smart URL Handling', () => {
+        let mockAxios;
+      
+        beforeAll(() => {
+          mockAxios = new MockAdapter(axios);
+        });
+
+        afterEach(() => {
+            mockAxios.reset();
+        });
+
+        afterAll(() => {
+            mockAxios.restore();
+        });
+      
+        test('should use original URL when valid without .ics', async () => {
+          const validUrl = 'https://cals.ftt.gmbh/calendar/germanholithunder';
+          mockAxios.onGet(validUrl).reply(200, 'VALID_CALENDAR');
+          
+          const result = await fetchCalendarData({ url: validUrl });
+          expect(result.data).toBe('VALID_CALENDAR');
+        });
+      
+        test('should try .ics version when original fails', async () => {
+          const invalidUrl = 'https://cals.ftt.gmbh/calendar/germanholithunder.ics';
+          const validUrl = invalidUrl.slice(0, -4);
+          
+          mockAxios
+            .onGet(invalidUrl).reply(404)
+            .onGet(validUrl).reply(200, 'VALID_CALENDAR');
+      
+          const result = await fetchCalendarData({ url: invalidUrl });
+          expect(result.data).toBe('VALID_CALENDAR');
+        });
+      
+        test('should preserve valid .ics URLs', async () => {
+          const googleUrl = 'https://calendar.google.com/.../basic.ics';
+          mockAxios.onGet(googleUrl).reply(200, 'GOOGLE_CALENDAR');
+          
+          const result = await fetchCalendarData({ url: googleUrl });
+          expect(result.data).toBe('GOOGLE_CALENDAR');
+        });
+      
+        test('should try both versions for ambiguous URLs', async () => {
+          const baseUrl = 'https://example.com/calendar';
+          const icsUrl = baseUrl + '.ics';
+          
+          mockAxios
+            .onGet(baseUrl).reply(404)
+            .onGet(icsUrl).reply(200, 'ICS_CALENDAR');
+      
+          const result = await fetchCalendarData({ url: baseUrl });
+          expect(result.data).toBe('ICS_CALENDAR');
+        });
+    });
 });
+