package com.sonymusic

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

import static org.junit.jupiter.api.Assertions.assertNull

class NpmRunTest extends BaseGlobalVarTest {
    def npmRun

    @BeforeEach
    void setUp() {
        super.setUp()
        npmRun = loadScript('vars/npmRun.groovy')

        helper.registerAllowedMethod('nodeSh', [Map])
        helper.registerAllowedMethod('readFile', [String], { String path ->
            if (path == 'package.json') {
                return '{"scripts": {"test": "jest", "lint": "eslint", "test:unit": "jest --unit"}}'
            }
            return '{}'
        })
        binding.setVariable('env', [:])
    }

    @Test
    void testCallWithNoArgs() {
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "npmRun: Missing required parameter: 'scriptNames'",
            { npmRun.call() }
        )
    }

    @Test
    void testCallWithScriptNames() {
        assertNull(
            npmRun(scriptNames: ['lint', 'test:unit'])
        )
        assertMethodCalledOnceWith('nodeSh', [
            'set -e',
            'npm run lint',
            'npm run test:unit'
        ])
    }

    @Test
    void testCallWithNodeVersion() {
        assertNull(
            npmRun(scriptNames: ['test'], nodeVersion: '22.1.1')
        )

        assertMethodCalledOnceWith('nodeSh', [
            'nodeVersion=22.1.1',
            'npm run test',
        ])
    }

    @Test
    void testCallWithNodeVersion24() {
        assertNull(
            npmRun(scriptNames: ['test'], nodeVersion: '24.5.0')
        )

        assertMethodCalledOnceWith('nodeSh', [
            'nodeVersion=24.5.0',
            'npm run test',
        ])
    }

    @Test
    void testCallWithEnvVars() {
        assertNull(
            npmRun(
                scriptNames: ['test'],
                envVars: [
                    TEST: 'value',
                ]
            )
        )

        assertMethodCalledOnceWith('nodeSh', [
            'envVars={TEST=value}',
            'npm run test'
        ])
    }

    @Test
    void testCallWithBinaryCommand() {
        assertNull(
            npmRun(scriptNames: ['frontend build --public-path /path/'])
        )
        assertMethodCalledOnceWith('nodeSh', [
            'set -e',
            'npm exec -- frontend build --public-path /path/'
        ])
    }

    @Test
    void testCallWithMixedScriptsAndBinaries() {
        assertNull(
            npmRun(scriptNames: ['frontend i18n:download', 'frontend build --public-path /path/', 'test'])
        )
        assertMethodCalledOnceWith('nodeSh', [
            'set -e',
            'npm exec -- frontend i18n:download',
            'npm exec -- frontend build --public-path /path/',
            'npm run test'
        ])
    }
}
