/**
* @jest-environment jsdom
*/

/*!
 * Copyright (c) 2023 Eclipse Foundation, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * Contributors:
 *   Olivier Goulet <olivier.goulet@eclipse-foundation.org>
 *
 * SPDX-License-Identifier: EPL-2.0
 */

import eclipsefdnProjects from '../eclipsefdn.projects';
import { generateMockProject, mockProjects } from '../../api/tests/mocks/projects/mock-data';
import * as projectsAPIModule from '../../api/eclipsefdn.projects';
import { waitForRender } from '../../utils/utils';

jest.mock('list.js');

import List from 'list.js';

describe('eclipsefdn-projects', () => {
    let getProjectsDataSpy;

    beforeEach(() => {
        getProjectsDataSpy = jest.spyOn(projectsAPIModule, 'getProjectsData');
        const originalList = new List();
        List.mockImplementation(() => ({
            ...originalList,
            on: jest.fn()
        }));
    });

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

    it('Renders static projects from a local JSON file', () => {
        getProjectsDataSpy.mockReturnValue([
            {
                "name": "Eclipse Che",
                "summary": "Eclipse Che is a Kubernetes-native IDE that makes Kubernetes development accessible for development teams, providing one-click developer workspaces and eliminating local environment configuration for your entire team.",
                "logo": "https://www.eclipse.org/che/images/che-logo-64.png",
                "category": "Tools",
                "website_url": "https://www.eclipse.org/che/",
                "version": "7.0.0",
                "state": "Active",
                "isProposal": false
            },
        ]);
        const staticSourceUrl = './static-projects.json';

        document.querySelector('body').innerHTML = `
            <div class="featured-projects" data-is-static-source="true" data-types="projects" data-url="${staticSourceUrl}"></div>
        `;
        
        eclipsefdnProjects.render();

        expect(getProjectsDataSpy).toHaveBeenCalledWith(staticSourceUrl, true);
    });

    it('Renders projects from an external source (ex. Projects API)', () => {
        getProjectsDataSpy.mockReturnValue([
            {
                "name": "Eclipse Che",
                "summary": "Eclipse Che is a Kubernetes-native IDE that makes Kubernetes development accessible for development teams, providing one-click developer workspaces and eliminating local environment configuration for your entire team.",
                "logo": "https://www.eclipse.org/che/images/che-logo-64.png",
                "category": "Tools",
                "website_url": "https://www.eclipse.org/che/",
                "version": "7.0.0",
                "state": "Active",
                "isProposal": false
            },
        ]);
    
        const url = 'https://api.eclipse.org/api/projects?working_group=internet-things-iot';

        document.querySelector('body').innerHTML = `
            <div class="featured-projects" data-is-static-source="false" data-types="projects" data-url="${url}"></div>
        `;
        
        eclipsefdnProjects.render();

        expect(getProjectsDataSpy).toHaveBeenCalledWith(url, false);
    });

    it('The page size option limits the number of projects displayed', async () => {
        const mockProjects = Array.from({ length: 5 }, () => generateMockProject());
        getProjectsDataSpy.mockReturnValue(mockProjects);

        const url = 'https://api.eclipse.org/api/projects?working_group=jakarta-ee';

        document.querySelector('body').innerHTML = `
            <div class="featured-projects" data-url="${url}" data-page-size="3"></div>
        `;

        const featuredProjectsElement = document.querySelector('.featured-projects');
        eclipsefdnProjects.render();

        await waitForRender(featuredProjectsElement);

        const projectElements = document.querySelectorAll('.featured-projects-item');

        expect(projectElements).toHaveLength(3);
    });

    it('Sorting method allows for random sorting of projects', async () => {
        // Just checking whether or not the Math.random() function is called
        // is enough to ensure that the sorting method is random. It wouldn't
        // be practical to test randomness.
        let randomSpy = jest.spyOn(Math, 'random');
        const mockProjects = Array.from({ length: 5 }, () => generateMockProject({ industryCollaboration: 'Jakarta EE' })); 
        getProjectsDataSpy.mockReturnValue(mockProjects);

        const url = 'https://api.eclipse.org/api/projects?working_group=jakarta-ee';

        document.querySelector('body').innerHTML = `
            <div class="featured-projects" data-url="${url}" data-sorting-method="random"></div>
        `
        
        const featuredProjectsElement = document.querySelector('.featured-projects');
        eclipsefdnProjects.render();
      
        await waitForRender(featuredProjectsElement);

        expect(randomSpy).toHaveBeenCalled();
    });
});
