internal HashSet <string> SplitAndNormalizeScopes(string target)
        {
            var scopes           = ScopeUtils.SplitScopes(target);
            var normalizedScopes = new HashSet <string>();

            foreach (string scope in scopes)
            {
                normalizedScopes.Add(NormalizeKey(scope));
            }

            return(normalizedScopes);
        }
        public TokenResponse(IdToken idToken, Credential accessToken, Credential refreshToken)
        {
            IdToken = idToken ?? new IdToken(string.Empty);
            if (accessToken != null)
            {
                AccessToken       = accessToken.Secret;
                ExpiresOn         = DateTime.UtcNow; // TODO: ToTimePoint(accessToken.ExpiresOn)
                ExtendedExpiresOn = DateTime.UtcNow; // TODO: ToTimePoint(accessToken.ExtendedExpiresOn)
                GrantedScopes     = ScopeUtils.SplitScopes(accessToken.Target);
            }

            if (refreshToken != null)
            {
                RefreshToken = refreshToken.Secret;
            }
        }
        public void RemoveAccessTokenWithScopes()
        {
            void CreateRemoveVerify(
                List <HashSet <string> > scopesBefore,
                HashSet <string> scopesToRemove,
                List <HashSet <string> > scopesAfter)
            {
                var accessTokens = new JObject();

                foreach (HashSet <string> s in scopesBefore)
                {
                    EmplaceAccessToken(accessTokens, s);
                }

                _storageWorker.RemoveAccessTokenWithScopes(accessTokens, JoinScopes(scopesToRemove));

                Assert.AreEqual(accessTokens.Count, scopesAfter.Count);

                foreach (HashSet <string> s in scopesAfter)
                {
                    foreach (KeyValuePair <string, JToken> kvp in accessTokens)
                    {
                        if (HashSetUtil.AreEqual(s, ScopeUtils.SplitScopes(kvp.Key)))
                        {
                            accessTokens.Remove(kvp.Key);
                            break;
                        }
                    }
                }

                Assert.IsTrue(accessTokens.IsEmpty());
            }

            CreateRemoveVerify(
                new List <HashSet <string> >(),
                new HashSet <string>
            {
                "a",
                "b"
            },
                new List <HashSet <string> >());
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                }
            },
                new HashSet <string>
            {
                "c",
                "d"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                }
            });
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "a",
                "b",
                "c",
                "d",
                "Z"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            });
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "Z"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            });
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "a"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            });
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "a",
                "b"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            });
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "a",
                "b",
                "c"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            });
            CreateRemoveVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                },
                new HashSet <string>
                {
                    "e",
                    "f"
                }
            },
                new HashSet <string>
            {
                "c"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "e",
                    "f"
                }
            });

            // ASSERT_MSAL_THROW(
            //    CreateRemoveVerify({}, {}, {}), MsalStorageException, StorageErrorCodes::NO_ACCESS_TOKEN_SCOPES_REQUESTED);
            // ASSERT_MSAL_THROW(
            //    CreateRemoveVerify({{"a"}}, {}, {}), MsalStorageException, StorageErrorCodes::NO_ACCESS_TOKEN_SCOPES_REQUESTED);
        }
        public void AddAccessTokenWithScopes()
        {
            void CreateAddVerify(
                List <HashSet <string> > scopesBefore,
                HashSet <string> scopesToAdd,
                List <HashSet <string> > scopesAfter)
            {
                var accessTokens = new JObject();

                foreach (HashSet <string> s in scopesBefore)
                {
                    EmplaceAccessToken(accessTokens, s);
                }

                _storageWorker.AddAccessTokenWithScopes(accessTokens, GetAccessTokenJsonWithScopes(scopesToAdd));

                Assert.AreEqual(accessTokens.Count, scopesAfter.Count);

                var keysToRemove = new List <string>();

                foreach (HashSet <string> s in scopesAfter)
                {
                    foreach (KeyValuePair <string, JToken> kvp in accessTokens)
                    {
                        if (HashSetUtil.AreEqual(s, ScopeUtils.SplitScopes(kvp.Key)))
                        {
                            keysToRemove.Add(kvp.Key);
                            break;
                        }
                    }
                }

                foreach (string keyToRemove in keysToRemove)
                {
                    accessTokens.Remove(keyToRemove);
                }

                Assert.IsTrue(accessTokens.IsEmpty());
            }

            CreateAddVerify(
                new List <HashSet <string> >(),
                new HashSet <string>
            {
                "a",
                "b"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                }
            });
            CreateAddVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                }
            },
                new HashSet <string>
            {
                "c",
                "d"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            });
            CreateAddVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "a",
                "b",
                "c",
                "d",
                "Z"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b",
                    "c",
                    "d",
                    "Z"
                }
            });
            CreateAddVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                }
            },
                new HashSet <string>
            {
                "a",
                "b",
                "c",
                "Z"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b",
                    "c",
                    "Z"
                }
            });
            CreateAddVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                },
                new HashSet <string>
                {
                    "e",
                    "f"
                }
            },
                new HashSet <string>
            {
                "a",
                "c",
                "e"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "c",
                    "e"
                }
            });
            CreateAddVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                },
                new HashSet <string>
                {
                    "e",
                    "f"
                }
            },
                new HashSet <string>
            {
                "a",
                "b",
                "c",
                "d",
                "e",
                "f"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b",
                    "c",
                    "d",
                    "e",
                    "f"
                }
            });
            CreateAddVerify(
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b"
                },
                new HashSet <string>
                {
                    "c",
                    "d"
                },
                new HashSet <string>
                {
                    "e",
                    "f"
                }
            },
                new HashSet <string>
            {
                "a",
                "b",
                "c",
                "Z"
            },
                new List <HashSet <string> >
            {
                new HashSet <string>
                {
                    "a",
                    "b",
                    "c",
                    "Z"
                },
                new HashSet <string>
                {
                    "e",
                    "f"
                }
            });

            // ASSERT_MSAL_THROW(createAddVerify({}, {}, {}), MsalStorageException, StorageErrorCodes::ACCESS_TOKEN_HAS_NO_SCOPES);
        }