Skip to content
Open
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
195 changes: 195 additions & 0 deletions __tests__/useful-friends-metrics.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// Mock VK-IO to avoid dynamic import issues in tests
jest.mock('vk-io', () => ({
VK: jest.fn()
}));

// Mock utils to avoid token file dependency
jest.mock('../utils', () => ({
getToken: jest.fn(),
sleep: jest.fn(),
second: 1000,
ms: 1,
saveJsonSync: jest.fn(),
readJsonSync: jest.fn()
}));

// Mock friends-cache
jest.mock('../friends-cache', () => ({
getAllFriends: jest.fn()
}));

const {
calculateFriendScore,
analyzeEducation,
analyzeOccupation,
analyzeTextFields,
containsKeywords,
PROGRAMMING_KEYWORDS,
TECH_UNIVERSITIES,
TECH_FACULTIES,
TECH_OCCUPATIONS
} = require('../useful-friends-metrics');

describe('useful-friends-metrics', () => {
describe('containsKeywords', () => {
it('should find programming keywords in text', () => {
expect(containsKeywords('I love programming', PROGRAMMING_KEYWORDS)).toBe(true);
expect(containsKeywords('JavaScript developer', PROGRAMMING_KEYWORDS)).toBe(true);
expect(containsKeywords('I study computer science', PROGRAMMING_KEYWORDS)).toBe(true); // computer is in keywords
expect(containsKeywords('I like music', PROGRAMMING_KEYWORDS)).toBe(false);
expect(containsKeywords(null, PROGRAMMING_KEYWORDS)).toBe(false);
expect(containsKeywords('', PROGRAMMING_KEYWORDS)).toBe(false);
});

it('should be case insensitive', () => {
expect(containsKeywords('PROGRAMMING', PROGRAMMING_KEYWORDS)).toBe(true);
expect(containsKeywords('Programming', PROGRAMMING_KEYWORDS)).toBe(true);
expect(containsKeywords('programming', PROGRAMMING_KEYWORDS)).toBe(true);
});
});

describe('analyzeEducation', () => {
it('should score tech universities higher', () => {
const universities = [
{ university_name: 'МГТУ им. Баумана', faculty_name: 'Информатика' }
];
const result = analyzeEducation(universities, null);
expect(result.score).toBeGreaterThan(0);
expect(result.reasons).toContain('Tech faculty: Информатика');
});

it('should handle empty education data', () => {
const result = analyzeEducation(null, null);
expect(result.score).toBe(0);
expect(result.reasons).toEqual([]);
});

it('should score tech faculties', () => {
const universities = [
{ university_name: 'Some University', faculty_name: 'Computer Science' }
];
const result = analyzeEducation(universities, null);
expect(result.score).toBe(2);
expect(result.reasons[0]).toContain('Tech faculty: Computer Science');
});
});

describe('analyzeOccupation', () => {
it('should score programming occupations highly', () => {
const occupation = { name: 'Software Developer' };
const result = analyzeOccupation(occupation);
expect(result.score).toBe(4);
expect(result.reasons[0]).toContain('Tech occupation: Software Developer');
});

it('should handle empty occupation', () => {
expect(analyzeOccupation(null).score).toBe(0);
expect(analyzeOccupation({}).score).toBe(0);
expect(analyzeOccupation({ name: null }).score).toBe(0);
});

it('should not score non-tech occupations', () => {
const occupation = { name: 'Teacher' };
const result = analyzeOccupation(occupation);
expect(result.score).toBe(0);
expect(result.reasons).toEqual([]);
});
});

describe('analyzeTextFields', () => {
it('should score programming interests', () => {
const user = {
interests: 'Programming, JavaScript, React',
activities: 'Coding, open source projects',
about: 'I am a web developer'
};
const result = analyzeTextFields(user);
expect(result.score).toBeGreaterThan(0);
expect(result.reasons.length).toBeGreaterThan(0);
});

it('should handle empty text fields', () => {
const user = {};
const result = analyzeTextFields(user);
expect(result.score).toBe(0);
expect(result.reasons).toEqual([]);
});

it('should weight interests and activities higher than about', () => {
const userWithInterests = { interests: 'programming' };
const userWithAbout = { about: 'programming' };

const interestsResult = analyzeTextFields(userWithInterests);
const aboutResult = analyzeTextFields(userWithAbout);

expect(interestsResult.score).toBeGreaterThan(aboutResult.score);
});
});

describe('calculateFriendScore', () => {
it('should calculate total score correctly', () => {
const friend = {
universities: [{ university_name: 'MIT', faculty_name: 'Computer Science' }],
occupation: { name: 'Software Engineer' },
interests: 'Programming, JavaScript',
activities: 'Coding',
about: 'Web developer'
};

const result = calculateFriendScore(friend);
expect(result.score).toBeGreaterThan(5); // Should be high score
expect(result.isUseful).toBe(true);
expect(result.reasons.length).toBeGreaterThan(0);
});

it('should mark friends as useful when score >= 2', () => {
const friend = {
interests: 'programming, web development' // Should give score of 2
};

const result = calculateFriendScore(friend);
expect(result.isUseful).toBe(true);
});

it('should not mark friends as useful when score < 2', () => {
const friend = {
about: 'I like music and art' // No programming keywords
};

const result = calculateFriendScore(friend);
expect(result.isUseful).toBe(false);
expect(result.score).toBe(0);
});

it('should handle friends with minimal data', () => {
const friend = {};
const result = calculateFriendScore(friend);
expect(result.score).toBe(0);
expect(result.isUseful).toBe(false);
expect(result.reasons).toEqual([]);
});
});

describe('keywords arrays', () => {
it('should have programming keywords', () => {
expect(PROGRAMMING_KEYWORDS).toContain('programming');
expect(PROGRAMMING_KEYWORDS).toContain('javascript');
expect(PROGRAMMING_KEYWORDS).toContain('developer');
});

it('should have tech universities', () => {
expect(TECH_UNIVERSITIES).toContain('mit');
expect(TECH_UNIVERSITIES).toContain('мгту');
});

it('should have tech faculties', () => {
expect(TECH_FACULTIES).toContain('computer science');
expect(TECH_FACULTIES).toContain('информатик');
});

it('should have tech occupations', () => {
expect(TECH_OCCUPATIONS).toContain('developer');
expect(TECH_OCCUPATIONS).toContain('программист');
});
});
});
116 changes: 116 additions & 0 deletions experiments/test-useful-friends-metrics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
const {
calculateFriendScore,
analyzeEducation,
analyzeOccupation,
analyzeTextFields,
containsKeywords,
PROGRAMMING_KEYWORDS
} = require('../useful-friends-metrics');

// Test data mimicking VK API response
const testFriends = [
{
id: 1,
first_name: 'John',
last_name: 'Doe',
universities: [
{ university_name: 'MIT', faculty_name: 'Computer Science' }
],
occupation: { name: 'Software Engineer' },
interests: 'Programming, JavaScript, React, Machine Learning',
activities: 'Open source projects, coding challenges',
about: 'Full-stack developer passionate about creating scalable web applications'
},
{
id: 2,
first_name: 'Jane',
last_name: 'Smith',
universities: [
{ university_name: 'Harvard University', faculty_name: 'Business Administration' }
],
occupation: { name: 'Marketing Manager' },
interests: 'Music, Travel, Photography',
activities: 'Social media marketing, event planning',
about: 'Marketing professional with a passion for creative campaigns'
},
{
id: 3,
first_name: 'Alex',
last_name: 'Johnson',
universities: [
{ university_name: 'МГТУ им. Баумана', faculty_name: 'Информатика и системы управления' }
],
interests: 'Программирование, алгоритмы, разработка игр',
about: 'Студент, изучаю веб-разработку и мобильные приложения'
},
{
id: 4,
first_name: 'Bob',
last_name: 'Wilson',
occupation: { name: 'Data Scientist' },
interests: 'Machine learning, Python, AI',
activities: 'Kaggle competitions, research papers'
},
{
id: 5,
first_name: 'Sarah',
last_name: 'Brown',
universities: [
{ university_name: 'Local Community College', faculty_name: 'Art' }
],
interests: 'Painting, Drawing, Sculpture',
activities: 'Art exhibitions, gallery visits',
about: 'Artist working with traditional and digital media'
}
];

function runTests() {
console.log('=== TESTING USEFUL FRIENDS METRICS ===\n');

testFriends.forEach((friend, index) => {
console.log(`Friend ${index + 1}: ${friend.first_name} ${friend.last_name}`);
const analysis = calculateFriendScore(friend);

console.log(`Score: ${analysis.score}`);
console.log(`Is Useful: ${analysis.isUseful ? 'YES' : 'NO'}`);
console.log('Reasons:');
analysis.reasons.forEach(reason => {
console.log(` - ${reason}`);
});

// Debug keyword detection
console.log('Debug - Text analysis:');
['interests', 'activities', 'about'].forEach(field => {
if (friend[field]) {
const hasKeywords = containsKeywords(friend[field], PROGRAMMING_KEYWORDS);
console.log(` ${field}: "${friend[field]}" -> ${hasKeywords ? 'MATCH' : 'NO MATCH'}`);
}
});
console.log('---\n');
});

// Test keyword detection
console.log('=== KEYWORD DETECTION TESTS ===\n');

const testTexts = [
'I love programming and web development',
'JavaScript and React developer',
'Программирование на Python',
'Music and art lover',
'Software engineer at Google',
'Студент МГТУ, изучаю информатику'
];

testTexts.forEach(text => {
const hasKeywords = containsKeywords(text, PROGRAMMING_KEYWORDS);
console.log(`"${text}" -> ${hasKeywords ? 'HAS' : 'NO'} programming keywords`);
});

console.log('\n=== SUMMARY ===');
const usefulFriends = testFriends.filter(friend => calculateFriendScore(friend).isUseful);
console.log(`Total friends: ${testFriends.length}`);
console.log(`Useful friends: ${usefulFriends.length}`);
console.log(`Percentage: ${((usefulFriends.length / testFriends.length) * 100).toFixed(1)}%`);
}

runTests();
Loading