756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington/*
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * The contents of this file are subject to the terms of the Common Development and
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * Distribution License (the License). You may not use this file except in compliance with the
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * License.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington *
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * specific language governing permission and limitations under the License.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington *
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * When distributing Covered Software, include this CDDL Header Notice in each file and include
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * Header, with the fields enclosed by brackets [] replaced by your own identifying
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * information: "Portions copyright [year] [name of copyright owner]".
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington *
af38905e8a5231702db169603d942d5d2e0c4332David Luna * Copyright 2014-2015 ForgeRock AS.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington */
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonpackage org.forgerock.oauth2.core;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport static org.mockito.BDDMockito.*;
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport static org.mockito.Mockito.mock;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonimport java.util.HashMap;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonimport java.util.HashSet;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonimport java.util.Map;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonimport java.util.Set;
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport org.forgerock.oauth2.core.exceptions.InvalidRequestException;
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport org.forgerock.oauth2.core.exceptions.ServerException;
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport org.forgerock.oauth2.core.exceptions.UnsupportedResponseTypeException;
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport org.testng.annotations.BeforeMethod;
af38905e8a5231702db169603d942d5d2e0c4332David Lunaimport org.testng.annotations.Test;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington/**
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * @since 12.0.0
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington */
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonpublic class ResponseTypeValidatorTest {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington private ResponseTypeValidator responseTypeValidator;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @BeforeMethod
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void setUp() {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator = new ResponseTypeValidator();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test (expectedExceptions = UnsupportedResponseTypeException.class)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldThrowUnsupportedResponseTypeExceptionWhenRequestedResponseTypesAreEmpty()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington throws ServerException, UnsupportedResponseTypeException, InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect UnsupportedResponseTypeException
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test (expectedExceptions = UnsupportedResponseTypeException.class)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldThrowUnsupportedResponseTypeExceptionWhenRequestedResponseTypesAreNull()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington throws ServerException, UnsupportedResponseTypeException, InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = null;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect UnsupportedResponseTypeException
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test (expectedExceptions = InvalidRequestException.class)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldThrowInvalidRequestExceptionWhenProviderAllowedRequestedResponseTypesAreEmpty()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington throws ServerException, UnsupportedResponseTypeException, InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Map<String, ResponseTypeHandler> providerResponseTypes = new HashMap<String, ResponseTypeHandler>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_A");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(providerSettings.getAllowedResponseTypes()).willReturn(providerResponseTypes);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect InvalidRequestException
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test (expectedExceptions = InvalidRequestException.class)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldThrowInvalidRequestExceptionWhenProviderAllowedRequestedResponseTypesAreNull()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington throws ServerException, UnsupportedResponseTypeException, InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Map<String, ResponseTypeHandler> providerResponseTypes = null;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_A");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(providerSettings.getAllowedResponseTypes()).willReturn(providerResponseTypes);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect InvalidRequestException
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test (expectedExceptions = UnsupportedResponseTypeException.class)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldThrowUnsupportedResponseTypeExceptionWhenNotAllResponseTypesAreAllowedByProvider()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington throws ServerException, UnsupportedResponseTypeException, InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Map<String, ResponseTypeHandler> providerResponseTypes = new HashMap<String, ResponseTypeHandler>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_A");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_B");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(providerSettings.getAllowedResponseTypes()).willReturn(providerResponseTypes);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington providerResponseTypes.put("RESPONSE_TYPE_A", null);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect UnsupportedResponseTypeException
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test (expectedExceptions = UnsupportedResponseTypeException.class)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldThrowUnsupportedResponseTypeExceptionWhenNotAllResponseTypesAreAllowedByClient()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington throws ServerException, UnsupportedResponseTypeException, InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Map<String, ResponseTypeHandler> providerResponseTypes = new HashMap<String, ResponseTypeHandler>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> clientAllowedResponseTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_A");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_B");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(providerSettings.getAllowedResponseTypes()).willReturn(providerResponseTypes);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington providerResponseTypes.put("RESPONSE_TYPE_A", null);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington providerResponseTypes.put("RESPONSE_TYPE_B", null);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(clientRegistration.getAllowedResponseTypes()).willReturn(clientAllowedResponseTypes);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington clientAllowedResponseTypes.add("RESPONSE_TYPE_A");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect UnsupportedResponseTypeException
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington @Test
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington public void validateShouldValidateResponseType() throws ServerException, UnsupportedResponseTypeException,
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington InvalidRequestException {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Given
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ClientRegistration clientRegistration = mock(ClientRegistration.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> requestedRequestTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington OAuth2ProviderSettings providerSettings = mock(OAuth2ProviderSettings.class);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Map<String, ResponseTypeHandler> providerResponseTypes = new HashMap<String, ResponseTypeHandler>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington Set<String> clientAllowedResponseTypes = new HashSet<String>();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_A");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington requestedRequestTypes.add("RESPONSE_TYPE_B");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(providerSettings.getAllowedResponseTypes()).willReturn(providerResponseTypes);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington providerResponseTypes.put("RESPONSE_TYPE_A", null);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington providerResponseTypes.put("RESPONSE_TYPE_B", null);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington given(clientRegistration.getAllowedResponseTypes()).willReturn(clientAllowedResponseTypes);
af38905e8a5231702db169603d942d5d2e0c4332David Luna clientAllowedResponseTypes.add("RESPONSE_TYPE_A RESPONSE_TYPE_B");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //When
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington responseTypeValidator.validate(clientRegistration, requestedRequestTypes, providerSettings);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington //Then
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington // Expect no exceptions
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}