package com.sonymusic

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

class SlackPrNotifyTest extends BaseGlobalVarTest {
    def slackPrNotify
    def response = [title: 'PR Title', html_url: 'pr.com', description: 'desc', user: [login: 'tim']]

    @BeforeEach
    void setUp() {
        super.setUp()
        slackPrNotify = loadScript('vars/slackPrNotify.groovy')
        binding.setVariable('env', ['CHANGE_ID': '100'])
        helper.registerAllowedMethod('withCredentials', [Map])
        helper.registerAllowedMethod('sh', [Map])
        helper.registerAllowedMethod('slackNotify', [Map])
        helper.registerAllowedMethod('readJSON', [Map], {
            return response
        })
    }

    @Test
    void testCallWithNoArgs() {
        assertThrowsWithMessage(
            IllegalArgumentException.class, 
            "slackPrNotify: Missing required parameter: 'repo'", 
            { slackPrNotify.call(message: 'test', channel: '#test') }
        )
        assertThrowsWithMessage(
            IllegalArgumentException.class, 
            "slackPrNotify: Missing required parameter: 'channel'", 
            { slackPrNotify.call(message: 'test', repo: '#test') }
        )
    }

    @Test
    void testCallWithNoPullRequestId() {
        binding.setVariable('env', [:])

        assertThrowsWithMessage(
            AssertionError.class, 
            "slackPrNotify: pullRequestId is required if env.CHANGE_ID is not available.", 
            { slackPrNotify.call(repo: 'frontend-test', message: 'test', channel: '#test') }
        )
    }

    @Test
    void testCallWithMessage() {
        def message = 'test message'

        slackPrNotify(
            repo: 'frontend-test',
            channel: '#test',
            message: message
        )

        assertMethodCalledOnceWith('withCredentials', '[GITHUB_TOKEN]')
        assertMethodCalledOnceWith('sh', [
            'curl -X GET -H "Authorization: token \${GITHUB_TOKEN}"',
            'https://api.github.com/repos/theorchard/frontend-test/pulls/100'
        ])

        assertMethodCalledOnceWith('slackNotify', [
            'channel=#test',
            "message=${response.title} (${response.user.login})\n${response.html_url}\n${message}"
        ])
    }

    @Test
    void testCallWithOwner() {
        slackPrNotify(
            repo: 'frontend-test',
            channel: '#test',
            owner: 'sme'
        )

        assertMethodCalledTimes('withCredentials', 1)
        assertMethodCalledOnceWith('sh', [
            'https://api.github.com/repos/sme/frontend-test/pulls/100'
        ])

        assertMethodCalledOnceWith('slackNotify', [
            'channel=#test',
            "message=${response.title} (${response.user.login})\n${response.html_url}\n${response.description}"
        ])
    }

    @Test
    void testCallWithPullRequestId() {
        slackPrNotify(
            repo: 'frontend-test',
            channel: '#test',
            pullRequestId: '200'
        )

        assertMethodCalledTimes('withCredentials', 1)
        assertMethodCalledOnceWith('sh', [
            'https://api.github.com/repos/theorchard/frontend-test/pulls/200'
        ])

        assertMethodCalledOnceWith('slackNotify', [
            'channel=#test',
            "message=${response.title} (${response.user.login})\n${response.html_url}\n${response.description}"
        ])
    }

    @Test
    void testCallWithChannel() {
        def channel = '#my-channel'

        slackPrNotify(
            repo: 'frontend-test',
            channel: channel,
        )

        assertMethodCalledTimes('withCredentials', 1)
        assertMethodCalledOnceWith('sh', [
            'https://api.github.com/repos/theorchard/frontend-test/pulls/100'
        ])

        assertMethodCalledOnceWith('slackNotify', [
            "channel=${channel}",
            "message=${response.title} (${response.user.login})\n${response.html_url}\n${response.description}"
        ])
    }
}
