Skip to content

Commit

Permalink
Merge pull request #95 from WSU-4110/Jesse_developMagic
Browse files Browse the repository at this point in the history
Fix tests
  • Loading branch information
JesseNaser authored Apr 16, 2024
2 parents f87f798 + 2c2f432 commit 02a4c47
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 126 deletions.
113 changes: 44 additions & 69 deletions tests/constructor.test.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,60 @@
const VideoModal = require('../scripts/videopage');

global.fetch = jest.fn(() => Promise.resolve({
ok: true,
json: () => Promise.resolve({ liked: true, likes: 10 })
}));
// Mocking the necessary DOM structure and behavior
document.body.innerHTML = `
<div id="modal" style="display: none;"></div>
<iframe id="videoFrame"></iframe>
<button class="close"></button>
<div class="video-card" data-video-id="123">
<div class="like-count"></div>
<button class="like-btn"></button>
</div>
`;

// Mocking global fetch
global.fetch = jest.fn();

describe('VideoModal', () => {
let videoModal;
beforeEach(() => {
// Reset all mocks between tests
fetch.mockClear();
document.getElementById.mockClear();
document.getElementsByClassName.mockClear();
document.querySelectorAll.mockClear();

// Set up mocks for document methods used in VideoModal
document.getElementById = jest.fn().mockImplementation(id => {
if (id === 'modal') return { style: { display: 'none' } };
if (id === 'videoFrame') return { src: '' };
return null;
// Reset fetch mock before each test
fetch.mockReset();

// Setup fetch mock response
fetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve({
liked: true,
likes: 10
})
});

document.getElementsByClassName = jest.fn().mockReturnValue([{
addEventListener: jest.fn()
}]);

document.querySelectorAll = jest.fn().mockReturnValue([...new Array(5)].map(() => ({
getAttribute: jest.fn().mockReturnValue('123'),
addEventListener: jest.fn(),
querySelector: jest.fn().mockReturnValue({
textContent: '',
classList: {
toggle: jest.fn()
},
innerHTML: ''
})
})));
// Initialize VideoModal instance
videoModal = new VideoModal('modal', 'videoFrame', 'close', '.video-card');
});

it('initializes and binds UI elements correctly', () => {
const videoModal = new VideoModal('modal', 'videoFrame', 'close', '.video-card');

// Check proper instantiation and method calls
expect(document.getElementById).toHaveBeenCalledWith('modal');
expect(document.getElementById).toHaveBeenCalledWith('videoFrame');
expect(document.getElementsByClassName).toHaveBeenCalledWith('close');
expect(document.querySelectorAll).toHaveBeenCalledWith('.video-card');

// Assert that properties are set up correctly
expect(videoModal.modal).toBeDefined();
expect(videoModal.videoFrame).toBeDefined();
expect(videoModal.closeButton).toBeDefined();
expect(videoModal.videoCards.length).toBe(5);
it('initializes class properties correctly', () => {
expect(videoModal.modal).toEqual(document.getElementById('modal'));
expect(videoModal.videoFrame).toEqual(document.getElementById('videoFrame'));
expect(videoModal.closeButton).toEqual(document.getElementsByClassName('close')[0]);
expect(videoModal.videoCards.length).toBe(1);
expect(videoModal.videoCards[0]).toEqual(document.querySelector('.video-card'));
});

it('updates like states correctly when initializing', async () => {
const videoModal = new VideoModal('modal', 'videoFrame', 'close', '.video-card');

// The updateAllLikeStates method should be called during initialization
await videoModal.init();

// Since there are 5 cards, ensure fetch was called 5 times
expect(fetch).toHaveBeenCalledTimes(5);
expect(fetch.mock.calls[0][0]).toBe('/api/likes?videoId=123');

const card = document.querySelectorAll().mock.results[0].value[0];
expect(card.querySelector.mock.calls.length).toBe(2); // Called twice per card: once for button, once for count
expect(card.querySelector().classList.toggle).toHaveBeenCalledWith('liked', true);
expect(card.querySelector().textContent).toBe('10 Likes');
});
it('calls fetch and updates like state for video cards', async () => {
// Trigger the update method which calls fetch
await videoModal.updateAllLikeStates();

it('handles modal opening and closing correctly', () => {
const videoModal = new VideoModal('modal', 'videoFrame', 'close', '.video-card');
videoModal.openModal('https://youtube.com/watch?v=dQw4w9WgXcQ');
// Check if fetch was called correctly
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith('/api/likes?videoId=123');

// Verify that the modal display style changes to block
expect(videoModal.modal.style.display).toBe('block');
expect(videoModal.videoFrame.src).toContain('https://youtube.com/embed/dQw4w9WgXcQ?autoplay=1&rel=0');
// Check changes to DOM (like count and button text)
const likesCountElement = videoModal.videoCards[0].querySelector('.like-count');
const likeButton = videoModal.videoCards[0].querySelector('.like-btn');

// Simulate closing the modal
videoModal.closeModal();
expect(videoModal.modal.style.display).toBe('none');
expect(videoModal.videoFrame.src).toBe('');
expect(likesCountElement.textContent).toBe('10 Likes');
expect(likeButton.classList.contains('liked')).toBe(true);
expect(likeButton.innerHTML).toContain('Liked');
});
});
72 changes: 39 additions & 33 deletions tests/openModal.test.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,53 @@
const VideoModal = require('../scripts/videopage');

// Mock fetch
global.fetch = jest.fn(() =>
Promise.resolve({
ok: true,
json: () => Promise.resolve({ likes: 10, liked: true })
})
);
// Setting up a full mock for fetch within Jest
beforeAll(() => {
global.fetch = jest.fn();
});

describe('VideoModal', () => {
let mockModal, mockVideoFrame, mockCards;
afterAll(() => {
global.fetch.mockRestore();
});

describe('VideoModal - openModal', () => {
let mockModal, mockVideoFrame;

beforeEach(() => {
fetch.mockClear();
// Clear mocks before each test
fetch.mockClear().mockResolvedValue({
ok: true,
json: () => Promise.resolve({ likes: 10, liked: true })
});

// Mock modal and videoFrame elements
mockModal = { style: { display: 'none' } };
mockVideoFrame = { src: '' };
mockCards = [{
getAttribute: jest.fn().mockReturnValue('123'),
querySelector: jest.fn().mockReturnValue({
textContent: '',
classList: {
toggle: jest.fn()
},
innerHTML: ''
})
}];

document.getElementById = jest.fn((id) => ({
'modal': mockModal,
'videoFrame': mockVideoFrame
})[id]);

document.getElementsByClassName = jest.fn().mockReturnValue([{ onclick: null }]);
document.querySelectorAll = jest.fn().mockReturnValue(mockCards);

// Using jest.spyOn to mock document API calls
jest.spyOn(document, 'getElementById').mockImplementation((id) => {
if (id === 'modal') return mockModal;
if (id === 'videoFrame') return mockVideoFrame;
return null;
});

// Mocking classes and query selectors
jest.spyOn(document, 'getElementsByClassName').mockReturnValue([{ onclick: jest.fn() }]);
jest.spyOn(document, 'querySelectorAll').mockReturnValue([{
addEventListener: jest.fn(),
getAttribute: jest.fn().mockReturnValue('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
}]);
});

afterEach(() => {
jest.restoreAllMocks();
});

it('updates all like states when initialized', async () => {
it('sets videoFrame src and displays modal', () => {
const videoModal = new VideoModal('modal', 'videoFrame', 'close', '.video-card');
await videoModal.updateAllLikeStates();
const testUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
videoModal.openModal(testUrl);

expect(fetch).toHaveBeenCalledTimes(mockCards.length);
expect(mockCards[0].querySelector).toHaveBeenCalledWith('.like-btn');
expect(mockCards[0].querySelector).toHaveBeenCalledWith('.like-count');
expect(mockVideoFrame.src).toContain('https://www.youtube.com/embed/dQw4w9WgXcQ?autoplay=1&rel=0');
expect(mockModal.style.display).toBe('block');
});
});
32 changes: 8 additions & 24 deletions tests/transformVideoUrl.test.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,24 @@
const VideoModal = require('../scripts/videopage');

global.fetch = jest.fn(() =>
Promise.resolve({
ok: true,
json: () => Promise.resolve({ likes: 10, liked: true })
})
);
// Mock fetch globally
global.fetch = jest.fn();

describe('VideoModal - transformVideoUrl', () => {
beforeEach(() => {
// Clear all mocks before each test
// Clear all mocks before each test to ensure clean slate
jest.clearAllMocks();

// Mock required DOM elements
document.getElementById = jest.fn(() => document.createElement('div'));
document.getElementsByClassName = jest.fn(() => [document.createElement('button')]);
document.querySelectorAll = jest.fn(() => [document.createElement('div')]);
});

it('transforms YouTube watch URL to embed URL correctly', () => {
// Mocking the necessary DOM elements
document.getElementById = jest.fn(id => {
if (id === 'dummyModalId') return document.createElement('div');
if (id === 'dummyVideoFrameId') return document.createElement('iframe');
return null;
});
document.getElementsByClassName = jest.fn((className) => {
if (className === 'dummyCloseButtonClass') return [document.createElement('button')];
return [];
});
document.querySelectorAll = jest.fn((selector) => {
if (selector === 'dummyVideoCardClass') return [document.createElement('div')];
return [];
});

const videoModal = new VideoModal('dummyModalId', 'dummyVideoFrameId', 'dummyCloseButtonClass', 'dummyVideoCardClass');
const inputUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
const expectedUrl = 'https://www.youtube.com/embed/dQw4w9WgXcQ';

expect(videoModal.transformVideoUrl(inputUrl)).toBe(expectedUrl);

expect(fetch).not.toHaveBeenCalled();
});
});

0 comments on commit 02a4c47

Please sign in to comment.