Skip to content

Commit 8cd3e60

Browse files
committed
ts
1 parent 558fb40 commit 8cd3e60

File tree

3 files changed

+434
-18
lines changed

3 files changed

+434
-18
lines changed

__tests__/generateHTML.test.js

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
const generateHTML = require('../src/generateHTML');
2+
3+
describe('generateHTML', () => {
4+
describe('with valid geolocation data', () => {
5+
const mockResult = {
6+
ip: '207.97.227.239',
7+
range: [3479299072, 3479299327],
8+
country: 'US',
9+
region: 'NY',
10+
eu: '0',
11+
timezone: 'America/New_York',
12+
city: 'New York',
13+
ll: [40.7128, -74.0060],
14+
metro: 501,
15+
area: 1000,
16+
};
17+
18+
it('should generate valid HTML with DOCTYPE', () => {
19+
const html = generateHTML(mockResult);
20+
expect(html).toContain('<!DOCTYPE html>');
21+
expect(html).toContain('<html>');
22+
expect(html).toContain('</html>');
23+
});
24+
25+
it('should include proper meta tags', () => {
26+
const html = generateHTML(mockResult);
27+
expect(html).toContain('<meta charset="UTF-8"');
28+
expect(html).toContain('<meta name="viewport"');
29+
expect(html).toContain('<meta name="author" content="Ahmed Tokyo">');
30+
expect(html).toContain('<title>Micro GeoIP Lite - Fast, Free and Open Source IP Geolocation Service</title>');
31+
});
32+
33+
it('should include Open Graph meta tags', () => {
34+
const html = generateHTML(mockResult);
35+
expect(html).toContain('<meta property="og:type" content="website">');
36+
expect(html).toContain('<meta property="og:title"');
37+
expect(html).toContain('<meta property="og:description"');
38+
expect(html).toContain('<meta property="og:image"');
39+
});
40+
41+
it('should include Twitter meta tags', () => {
42+
const html = generateHTML(mockResult);
43+
expect(html).toContain('<meta property="twitter:card"');
44+
expect(html).toContain('<meta property="twitter:title"');
45+
expect(html).toContain('<meta property="twitter:description"');
46+
});
47+
48+
it('should display geolocation data in details section', () => {
49+
const html = generateHTML(mockResult);
50+
expect(html).toContain('<h2>Details</h2>');
51+
expect(html).toContain('<strong>ip:</strong> 207.97.227.239');
52+
expect(html).toContain('<strong>country:</strong> US');
53+
expect(html).toContain('<strong>city:</strong> New York');
54+
expect(html).toContain('<strong>timezone:</strong> America/New_York');
55+
});
56+
57+
it('should include JSON data section', () => {
58+
const html = generateHTML(mockResult);
59+
expect(html).toContain('<h2>Raw JSON Data</h2>');
60+
expect(html).toContain('class="json-code"');
61+
expect(html).toContain('"ip": "207.97.227.239"');
62+
expect(html).toContain('"country": "US"');
63+
});
64+
65+
it('should include mobile ad container with ID', () => {
66+
const html = generateHTML(mockResult);
67+
expect(html).toContain('id="mobile-ad-container"');
68+
expect(html).toContain('class="mobile-ad"');
69+
});
70+
71+
it('should include desktop ad slot', () => {
72+
const html = generateHTML(mockResult);
73+
expect(html).toContain('data-ad-slot="8543379979"');
74+
expect(html).toContain('data-ad-client="ca-pub-5266987079964279"');
75+
expect(html).toContain('data-ad-format="auto"');
76+
});
77+
78+
it('should include AdSense script', () => {
79+
const html = generateHTML(mockResult);
80+
expect(html).toContain('pagead2.googlesyndication.com/pagead/js/adsbygoogle.js');
81+
expect(html).toContain('client=ca-pub-5266987079964279');
82+
});
83+
84+
it('should include mobile ad injection JavaScript', () => {
85+
const html = generateHTML(mockResult);
86+
expect(html).toContain('document.addEventListener(\'DOMContentLoaded\'');
87+
expect(html).toContain('window.innerWidth < 768');
88+
expect(html).toContain('data-ad-slot="9567852882"');
89+
expect(html).toContain('window.adsbygoogle.push({})');
90+
});
91+
92+
it('should include SEO content section', () => {
93+
const html = generateHTML(mockResult);
94+
expect(html).toContain('class="seo-content"');
95+
expect(html).toContain('Free & Open Source IP Geolocation API');
96+
expect(html).toContain('Why Choose Micro GeoIP Lite?');
97+
expect(html).toContain('Perfect for Backend Development');
98+
expect(html).toContain('Frontend & Client-Side Integration');
99+
});
100+
101+
it('should include use cases section', () => {
102+
const html = generateHTML(mockResult);
103+
expect(html).toContain('class="use-cases"');
104+
expect(html).toContain('E-commerce');
105+
expect(html).toContain('Security');
106+
expect(html).toContain('Analytics');
107+
expect(html).toContain('Content');
108+
});
109+
110+
it('should include NPM package information', () => {
111+
const html = generateHTML(mockResult);
112+
expect(html).toContain('npm install micro-geoip-lite');
113+
expect(html).toContain('import geodecodeIp from \'micro-geoip-lite\'');
114+
expect(html).toContain('https://www.npmjs.com/package/micro-geoip-lite');
115+
});
116+
});
117+
118+
describe('with error data', () => {
119+
const errorResult = {
120+
error: 'Please only submit valid IPs'
121+
};
122+
123+
it('should display error message', () => {
124+
const html = generateHTML(errorResult);
125+
expect(html).toContain('<h2>Error</h2>');
126+
expect(html).toContain('class="error-container"');
127+
expect(html).toContain('❌ Please only submit valid IPs');
128+
});
129+
130+
it('should include error help text', () => {
131+
const html = generateHTML(errorResult);
132+
expect(html).toContain('Please check your IP address and try again');
133+
expect(html).toContain('Examples of valid IPs:');
134+
expect(html).toContain('8.8.8.8 (Google DNS)');
135+
expect(html).toContain('1.1.1.1 (Cloudflare DNS)');
136+
});
137+
138+
it('should still include JSON data section with error', () => {
139+
const html = generateHTML(errorResult);
140+
expect(html).toContain('<h2>Raw JSON Data</h2>');
141+
expect(html).toContain('"error": "Please only submit valid IPs"');
142+
});
143+
144+
it('should still include all meta tags and SEO content', () => {
145+
const html = generateHTML(errorResult);
146+
expect(html).toContain('<title>Micro GeoIP Lite');
147+
expect(html).toContain('class="seo-content"');
148+
expect(html).toContain('Free & Open Source IP Geolocation API');
149+
});
150+
151+
it('should handle error result with additional data properties', () => {
152+
const errorWithData = {
153+
error: 'Lookup failed',
154+
ip: '192.168.1.1',
155+
attempted: true
156+
};
157+
const html = generateHTML(errorWithData);
158+
expect(html).toContain('<h2>Error</h2>');
159+
expect(html).toContain('❌ Lookup failed');
160+
expect(html).toContain('"error": "Lookup failed"');
161+
expect(html).toContain('"ip": "192.168.1.1"');
162+
expect(html).toContain('"attempted": true');
163+
});
164+
});
165+
166+
describe('with empty/null data', () => {
167+
it('should handle null result', () => {
168+
const html = generateHTML(null);
169+
expect(html).toContain('class="no-data"');
170+
expect(html).toContain('No geolocation data available');
171+
});
172+
173+
it('should handle empty object', () => {
174+
const html = generateHTML({});
175+
expect(html).toContain('class="no-data"');
176+
expect(html).toContain('No geolocation data available');
177+
});
178+
179+
it('should handle undefined result', () => {
180+
const html = generateHTML(undefined);
181+
expect(html).toContain('class="no-data"');
182+
expect(html).toContain('No geolocation data available');
183+
});
184+
});
185+
186+
describe('CSS and styling', () => {
187+
const mockResult = { ip: '8.8.8.8', country: 'US' };
188+
189+
it('should include responsive CSS grid', () => {
190+
const html = generateHTML(mockResult);
191+
expect(html).toContain('.content-grid');
192+
expect(html).toContain('grid-template-columns: 1fr');
193+
expect(html).toContain('@media (min-width: 768px)');
194+
});
195+
196+
it('should include mobile ad CSS rules', () => {
197+
const html = generateHTML(mockResult);
198+
expect(html).toContain('.mobile-ad');
199+
expect(html).toContain('display: block');
200+
expect(html).toContain('display: none');
201+
});
202+
203+
it('should include error container styling', () => {
204+
const html = generateHTML(mockResult);
205+
expect(html).toContain('.error-container');
206+
expect(html).toContain('background: #fee');
207+
expect(html).toContain('border: 2px solid #e74c3c');
208+
});
209+
210+
it('should include JSON container styling', () => {
211+
const html = generateHTML(mockResult);
212+
expect(html).toContain('.json-container');
213+
expect(html).toContain('background: #2d3748');
214+
expect(html).toContain('.json-code');
215+
});
216+
});
217+
218+
describe('JavaScript functionality', () => {
219+
const mockResult = { ip: '8.8.8.8', country: 'US' };
220+
221+
it('should include mobile detection logic', () => {
222+
const html = generateHTML(mockResult);
223+
expect(html).toContain('const isMobile = window.innerWidth < 768');
224+
expect(html).toContain('getElementById(\'mobile-ad-container\')');
225+
});
226+
227+
it('should include conditional ad injection', () => {
228+
const html = generateHTML(mockResult);
229+
expect(html).toContain('if (isMobile && mobileAdContainer)');
230+
expect(html).toContain('mobileAdContainer.innerHTML =');
231+
expect(html).toContain('mobileAdContainer.style.display = \'block\'');
232+
expect(html).toContain('mobileAdContainer.style.display = \'none\'');
233+
});
234+
235+
it('should include AdSense initialization', () => {
236+
const html = generateHTML(mockResult);
237+
expect(html).toContain('window.adsbygoogle = window.adsbygoogle || []');
238+
expect(html).toContain('window.adsbygoogle.push({})');
239+
});
240+
});
241+
});

0 commit comments

Comments
 (0)