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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"devDependencies": {
"eslint": "^8.38.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^30.0.0-beta.3",
"nodemon": "^2.0.22",
"supertest": "^6.3.3"
},
Expand Down
48 changes: 34 additions & 14 deletions public/js/vivid-market.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/**
* Placeholder function for initializing notifications.
* TODO: Implement actual notification initialization logic.
* Initialize the notification system by creating a toast container
* if it doesn't already exist. This container will hold all
* notification elements.
*/
function initializeNotifications() {
console.warn('initializeNotifications function called, but not implemented.');
let container = document.querySelector('.notification-container');
if (!container) {
container = document.createElement('div');
container.className = 'notification-container';
document.body.appendChild(container);
}
Comment on lines 6 to +12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function initializeNotifications directly manipulates the DOM to ensure a notification container exists. While this is functional, it could lead to inefficiencies if called multiple times, as each call involves querying and potentially modifying the DOM.

Recommendation: Consider checking and initializing the notification container once and reusing it, or using a more efficient method to manage DOM updates, such as using a JavaScript framework that handles the DOM more efficiently.

}
/**
* Vivid Market JavaScript
Expand Down Expand Up @@ -217,26 +223,31 @@ function initializeItemPreviews() {
* @param {string} type - Notification type (success, error, info)
*/
function showNotification(message, type = 'info') {
// Create notification element if it doesn't exist
let notification = document.querySelector('.notification');
if (!notification) {
notification = document.createElement('div');
notification.className = 'notification';
document.body.appendChild(notification);
}
// Ensure container exists
initializeNotifications();

// Set notification content and type
notification.textContent = message;
const container = document.querySelector('.notification-container');

// Create individual toast element
const notification = document.createElement('div');
notification.className = `notification ${type}`;
notification.textContent = message;

container.appendChild(notification);

// Show notification
// Trigger show animation
setTimeout(() => {
notification.classList.add('show');
}, 10);

// Hide notification after 3 seconds
// Hide and remove after 3 seconds
setTimeout(() => {
notification.classList.remove('show');
notification.addEventListener(
'transitionend',
() => notification.remove(),
{ once: true }
);
}, 3000);
}

Comment on lines 223 to 253
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The showNotification function lacks error handling for DOM operations, which could lead to runtime errors if the DOM structure changes or if elements are not found. Additionally, the use of multiple setTimeout functions for handling the display and removal of notifications could be optimized.

Recommendation: Implement error handling to check if elements are successfully found or created before proceeding with further actions. Consider consolidating or managing timeouts more efficiently to prevent potential memory leaks or performance issues.

Expand Down Expand Up @@ -377,3 +388,12 @@ function initializePurchaseFlow() {
function isUserLoggedIn() {
return document.body.classList.contains('user-logged-in');
}

// Export functions for testing in Node environments
if (typeof module !== 'undefined') {
module.exports = {
initializeNotifications,
showNotification,
isUserLoggedIn
};
}
34 changes: 34 additions & 0 deletions tests/vivid-market-notifications.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @jest-environment jsdom
*/
const { initializeNotifications, showNotification } = require('../public/js/vivid-market');

describe('Vivid Market Notifications', () => {
beforeEach(() => {
document.body.innerHTML = '';

Check failure on line 8 in tests/vivid-market-notifications.test.js

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tests/vivid-market-notifications.test.js#L8

'document' is not defined.
});

test('initializeNotifications creates a container', () => {
initializeNotifications();
const container = document.querySelector('.notification-container');

Check failure on line 13 in tests/vivid-market-notifications.test.js

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tests/vivid-market-notifications.test.js#L13

'document' is not defined.
expect(container).not.toBeNull();
});

test('showNotification appends a toast', () => {
jest.useFakeTimers();
initializeNotifications();
showNotification('Test', 'success');

const container = document.querySelector('.notification-container');
expect(container.children.length).toBe(1);

const toast = container.firstElementChild;
expect(toast.textContent).toBe('Test');
expect(toast.classList.contains('success')).toBe(true);

jest.advanceTimersByTime(20);
expect(toast.classList.contains('show')).toBe(true);

jest.useRealTimers();
Comment on lines +18 to +32
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handling of fake timers in the test 'showNotification appends a toast' is potentially problematic. The timers are set to fake with jest.useFakeTimers() at the beginning of the test, but they are only reset to real timers at the end of the test (jest.useRealTimers()). If the test fails or errors out before reaching the reset call, the timers remain in a fake state, which could affect subsequent tests.

Recommendation:
To ensure robustness and isolation, consider wrapping the test logic in a try...finally block, where jest.useRealTimers() is called in the finally block. This ensures that the timers are always reset, regardless of whether the test passes or fails.

});
});