/*
   Alice has removed Dave's rights to EDIT, so EDIT needs removing from the
   active Dave -> Ed policy, and adding to an inactive policy.
  */
  @Test
  public void shouldRemoveLostRights() throws Exception {
    // Given
    List<Resource> policies = excludePolicies(DAVE, ED);
    policies.add(makePolicy(DAVE, ED, true, VIEW, DELETE, EDIT));

    PolicyGraph graph = makePolicyGraph(policies);
    graph.computeGraph();

    given(resourceSetStore.read(anyString()))
        .willReturn(new ResourceSetDescription(RESOURCE_SET_ID, "RESOURCE_SERVER_ID", ALICE, null));

    given(delegate.updatePolicies(isNull(ServerContext.class), anySet()))
        .willReturn(
            Promises.<List<Resource>, ResourceException>newResultPromise(
                Collections.<Resource>emptyList()));

    given(delegate.createPolicies(isNull(ServerContext.class), anySet()))
        .willReturn(
            Promises.<List<Resource>, ResourceException>newResultPromise(
                Collections.<Resource>emptyList()));

    // When
    Promise<List<List<Resource>>, ResourceException> promise = graph.update(null, delegate);

    // Then
    AssertJPromiseAssert.assertThat(promise).succeeded();
    JsonValue created = policyCreated();
    assertThat(UmaPolicyUtils.getPolicyScopes(created)).containsOnly(EDIT);
    assertThat(created.get("active").asBoolean()).isFalse();
    assertThat(UmaPolicyUtils.getPolicyScopes(policyUpdated())).containsOnly(VIEW, DELETE);
    verifyNoMoreInteractions(delegate);
  }
  /*
   Dave had previously re-shared VIEW scope to ED, but that was made invalid when
   he lost that scope himself. He has been re-granted that scope so the VIEW scope
   should move the active policy and the empty inactive policy should be deleted.
  */
  @Test
  public void shouldUpdateInvalidRightsTree() throws Exception {
    // Given
    List<Resource> policies = excludePolicies(DAVE, ED);
    policies.add(makePolicy(DAVE, ED, true, DELETE));
    policies.add(makePolicy(DAVE, ED, false, VIEW));

    PolicyGraph graph = makePolicyGraph(policies);
    graph.computeGraph();

    given(delegate.updatePolicies(isNull(ServerContext.class), anySet()))
        .willReturn(
            Promises.<List<Resource>, ResourceException>newResultPromise(
                Collections.<Resource>emptyList()));

    given(delegate.deletePolicies(isNull(ServerContext.class), anySet()))
        .willReturn(
            Promises.<List<Resource>, ResourceException>newResultPromise(
                Collections.<Resource>emptyList()));

    // When
    Promise<List<List<Resource>>, ResourceException> promise = graph.update(null, delegate);

    // Then
    AssertJPromiseAssert.assertThat(promise).succeeded();
    assertThat(UmaPolicyUtils.getPolicyScopes(policyUpdated())).containsOnly(VIEW, DELETE);
    assertThat(policyDeleted()).isEqualTo("Dave-Ed-false");
    verifyNoMoreInteractions(delegate);
  }
  /*
   Dave had removed Ed's ability to DELETE, so Ed's resharing policy to Bob had been
   made inactive. Dave has re-granted Ed's DELETE, so the inactive policy can be made
   active again.
  */
  @Test
  public void shouldSwitchAllScopesInvalid() throws Exception {
    // Given
    List<Resource> policies = excludePolicies(ED, BOB);
    policies.add(makePolicy(ED, BOB, false, DELETE));

    PolicyGraph graph = makePolicyGraph(policies);
    graph.computeGraph();

    given(delegate.updatePolicies(isNull(ServerContext.class), anySet()))
        .willReturn(
            Promises.<List<Resource>, ResourceException>newResultPromise(
                Collections.<Resource>emptyList()));

    // When
    Promise<List<List<Resource>>, ResourceException> promise = graph.update(null, delegate);

    // Then
    AssertJPromiseAssert.assertThat(promise).succeeded();
    assertThat(policyUpdated().get("active").asBoolean()).isTrue();
    verifyNoMoreInteractions(delegate);
  }