import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import type { WorkflowTestData } from 'n8n-workflow';
import * as OTPAuth from 'otpauth';

describe('Execute TOTP node', () => {
	const testHarness = new NodeTestHarness();

	// Test constants
	const FIXED_TIMESTAMP = 1640000000000; // 2021-12-20T11:33:20.000Z
	const TEST_SECRET = 'BVDRSBXQB2ZEL5HE';
	const TEST_LABEL = 'GitHub:john-doe';

	beforeEach(() => {
		jest.spyOn(Date, 'now').mockReturnValue(FIXED_TIMESTAMP);
	});

	// Pre-calculate expected token using the real OTPAuth library
	// Note: The token value is the same whether label/issuer is present or not,
	// since those fields are metadata and don't affect the TOTP algorithm
	const expectedToken = new OTPAuth.TOTP({
		secret: TEST_SECRET,
		algorithm: 'SHA1',
		digits: 6,
		period: 30,
	}).generate({ timestamp: FIXED_TIMESTAMP });

	const tests: WorkflowTestData[] = [
		{
			description: 'Generate TOTP Token with label',
			input: {
				workflowData: testHarness.readWorkflowJSON('Totp.workflow.test.json'),
			},
			output: {
				nodeData: {
					TOTP: [[{ json: expect.objectContaining({ token: expectedToken }) }]],
				},
			},
			credentials: {
				totpApi: {
					label: TEST_LABEL,
					secret: TEST_SECRET,
				},
			},
		},
		{
			description: 'Generate TOTP Token without label',
			input: {
				workflowData: testHarness.readWorkflowJSON('Totp.workflow.test.json'),
			},
			output: {
				nodeData: {
					// When no label is provided, the node should still generate a valid token
					TOTP: [[{ json: expect.objectContaining({ token: expectedToken }) }]],
				},
			},
			credentials: {
				totpApi: {
					secret: TEST_SECRET,
				},
			},
		},
	];

	for (const testData of tests) {
		testHarness.setupTest(testData);
	}
});
