SocialAuthProviderParserTests.cs 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Infrastructure.Authentication;
  2. namespace Application.Tests;
  3. [TestClass]
  4. public sealed class SocialAuthProviderParserTests
  5. {
  6. [TestMethod]
  7. public void Naver_ParseUserInfo_MapsFields_EmailAlwaysUnverified()
  8. {
  9. // 네이버 프로필 표준 응답 — email 은 연락처 이메일이라 항상 EmailVerified=false 로 매핑되어야 한다 (d5 §③)
  10. const string json = """
  11. {"resultcode":"00","message":"success","response":{"id":"32742776","nickname":"개미","profile_image":"https://ssl.pstatic.net/img.png","email":"ant@example.com","name":"홍길동"}}
  12. """;
  13. var info = NaverAuthProvider.ParseUserInfo(json);
  14. Assert.IsNotNull(info);
  15. Assert.AreEqual("32742776", info.ProviderUserKey);
  16. Assert.AreEqual("ant@example.com", info.Email);
  17. Assert.IsFalse(info.EmailVerified, "네이버 이메일은 검증 플래그가 없어 항상 미검증 취급한다");
  18. Assert.AreEqual("개미", info.Nickname);
  19. Assert.AreEqual("https://ssl.pstatic.net/img.png", info.ProfileImageUrl);
  20. // resultcode 00 외에는 실패
  21. Assert.IsNull(NaverAuthProvider.ParseUserInfo("""{"resultcode":"024","message":"Authentication failed"}"""));
  22. }
  23. [TestMethod]
  24. public void Naver_ParseTokens_StringExpiresIn_And_ErrorBody()
  25. {
  26. // 네이버 토큰 응답은 expires_in 이 문자열("3600")로 온다 + 오류가 200 으로 내려오는 케이스(error 필드)도 걸러야 한다
  27. const string json = """
  28. {"access_token":"AAAAQosjWDJieBiQZc3to9YQp6HDLNzYyBYyO8","refresh_token":"c8ceMEJisO4Se7uGisHoX0f5JEii7JnipglQipkOn5Zp3tyP7dHQoP0zNKHUq2gY","token_type":"bearer","expires_in":"3600"}
  29. """;
  30. var before = DateTime.UtcNow;
  31. var tokens = NaverAuthProvider.ParseTokens(json);
  32. Assert.IsNotNull(tokens);
  33. Assert.AreEqual("AAAAQosjWDJieBiQZc3to9YQp6HDLNzYyBYyO8", tokens.AccessToken);
  34. Assert.IsNotNull(tokens.RefreshToken);
  35. Assert.IsTrue(tokens.ExpiresAt > before.AddSeconds(3000) && tokens.ExpiresAt <= before.AddSeconds(3600), "문자열 expires_in(3600)이 파싱되어야 한다");
  36. Assert.IsNull(NaverAuthProvider.ParseTokens("""{"error":"invalid_request","error_description":"no valid data in session"}"""), "error 필드가 있으면 실패로 처리한다");
  37. }
  38. [TestMethod]
  39. public void Kakao_ParseUserInfo_VerifiedEmail_MapsFields()
  40. {
  41. // 카카오 v2/user/me — id 는 int64, 검증된 이메일은 EmailVerified=true 로 매핑
  42. const string json = """
  43. {"id":123456789,"connected_at":"2026-07-03T01:00:00Z","kakao_account":{"profile_nickname_needs_agreement":false,"profile":{"nickname":"개미왕","thumbnail_image_url":"https://k.kakaocdn.net/thumb.jpg","profile_image_url":"https://k.kakaocdn.net/profile.jpg"},"has_email":true,"email_needs_agreement":false,"is_email_valid":true,"is_email_verified":true,"email":"ant@kakao.com"}}
  44. """;
  45. var info = KakaoAuthProvider.ParseUserInfo(json);
  46. Assert.IsNotNull(info);
  47. Assert.AreEqual("123456789", info.ProviderUserKey, "int64 id 는 문자열화하여 ProviderUserKey 로 쓴다");
  48. Assert.AreEqual("ant@kakao.com", info.Email);
  49. Assert.IsTrue(info.EmailVerified);
  50. Assert.AreEqual("개미왕", info.Nickname);
  51. Assert.AreEqual("https://k.kakaocdn.net/profile.jpg", info.ProfileImageUrl);
  52. }
  53. [TestMethod]
  54. public void Kakao_ParseUserInfo_EmailNotAgreed_ReturnsNullEmail()
  55. {
  56. // 카카오 account_email 은 선택동의 — 미동의 시 email 부재 → Email null (핸들러가 Auth.EmailRequired 로 분기)
  57. const string json = """
  58. {"id":987654321,"kakao_account":{"profile":{"nickname":"미동의개미"},"has_email":true,"email_needs_agreement":true}}
  59. """;
  60. var info = KakaoAuthProvider.ParseUserInfo(json);
  61. Assert.IsNotNull(info);
  62. Assert.AreEqual("987654321", info.ProviderUserKey);
  63. Assert.IsNull(info.Email, "이메일 미동의 시 null 이어야 한다");
  64. Assert.IsFalse(info.EmailVerified);
  65. Assert.AreEqual("미동의개미", info.Nickname);
  66. }
  67. }