#include "pch.h"
#include "../../lib/Shared/Internal.h"
#include "../../lib/Shared/http/HttpRequestUtil.h"
#include "Utilities.h"
#ifndef GTEST_OS_WINDOWS
# include "AuthTest.h"
#endif

using namespace TwitchInGames;

TEST(AuthTest, UrlEncode_Success) {
#ifdef _UNICODE
	auto result= UrlEncode(_T("\x99a!b@c#d$e%f^g&h*i(j)k-l_m=n+o`p~q[r{s]t}u\\v|w;x:y'z\"0/1?2,3<4.5>\x99"));
	EXPECT_EQ(result, _T("%E0%A6%9A%21b%40c%23d%24e%25f%5Eg%26h%2Ai%28j%29k-l_m%3Dn%2Bo%60p~q%5Br%7Bs%5Dt%7Du%5Cv%7Cw%3Bx%3Ay%27z%220%2F1%3F2%2C3%3C4.5%3E%C2%99"));
#else
	auto result= UrlEncode(_T("\x99 a!b@c#d$e%f^g&h*i(j)k-l_m=n+o`p~q[r{s]t}u\\v|w;x:y'z\"0/1?2,3<4.5>\x99"));
	EXPECT_EQ(result, _T("%99%20a%21b%40c%23d%24e%25f%5Eg%26h%2Ai%28j%29k-l_m%3Dn%2Bo%60p~q%5Br%7Bs%5Dt%7Du%5Cv%7Cw%3Bx%3Ay%27z%220%2F1%3F2%2C3%3C4.5%3E%99"));
#endif
}

TEST(AuthTest, ClientAuth_Success) {
#ifdef _XBOX_ONE
	Utilities::WriteWarning("no client auth on Xbox One");
	EXPECT_TRUE(true);
#else
	ClientAuth clientAuth;
	auto tokenTask= clientAuth.StartAuth(_T("clientId"), _T("redirect:uri"), Utilities::scopes);
	tstring token;
	auto fn= [&token, &tokenTask] {
		token= tokenTask.get();
	};
	auto waitTask= std::async(std::launch::async, fn);
	clientAuth.Cancel();
	waitTask.get();
	EXPECT_TRUE(token.empty());
#endif
}

TEST(AuthTest, ClientAuth_StartAuthTwice) {
#ifdef _XBOX_ONE
	Utilities::WriteWarning("no client auth on Xbox One");
	EXPECT_TRUE(true);
#else
	ClientAuth clientAuth;
	auto task= clientAuth.StartAuth(_T("clientId"), _T("redirect:uri"), Utilities::scopes);
	EXPECT_ANY_THROW(clientAuth.StartAuth(_T("clientId"), _T("redirect:uri"), Utilities::scopes));
#endif
}

TEST(AuthTest, ClientAuth_BadRedirectUri) {
#ifdef _XBOX_ONE
	Utilities::WriteWarning("no client auth on Xbox One");
	EXPECT_TRUE(true);
#else
	ClientAuth clientAuth;
	EXPECT_ANY_THROW(clientAuth.StartAuth(_T("clientId"), _T("redirectUri"), Utilities::scopes));
#endif
}

TEST(AuthTest, ServerAuth_Success) {
	ServerAuth serverAuth;
	tstring state;
	serverAuth.StartAuth(_T("clientId"), _T("redirectUri"), Utilities::scopes, state);
	EXPECT_TRUE(state.size() == 32);
	serverAuth.Finish(_T("accessToken"), _T("refreshToken"));
	auto accessToken= serverAuth.AccessToken;
	EXPECT_EQ(accessToken, _T("accessToken"));
}
