/*
* JBoss, Home of Professional Open Source
* Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.validator.test.internal.engine.packageprivateconstraint;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import org.hibernate.validator.testutil.TestForIssue;
import org.hibernate.validator.testutil.ValidatorUtil;

import static org.testng.Assert.assertEquals;

/**
 * Tests the validation of package-private constraints.
 *
 * @author Gunnar Morling
 */
@TestForIssue(jiraKey = "HV-843")
public class PackagePrivateConstraintValidationTest {

	private Validator validator;

	@BeforeMethod
	public void setupValidator() {
		validator = ValidatorUtil.getValidator();
	}

	@Test
	public void shouldValidatePackagePrivateConstraint() {
		Set<ConstraintViolation<Giraffe>> violations = validator.validate( new Giraffe() );
		assertEquals( violations.size(), 1 );
		assertEquals(
				violations.iterator().next().getConstraintDescriptor().getAnnotation().annotationType(),
				ValidAnimalName.class
		);
	}

	/**
	 * Currently it's not possible to have an annotation which is declared as inner-type within a package-private
	 * annotation type and have that inner annotation refer to that outer annotation type.
	 * <p>
	 * That means it is not possible to work with the conventional pattern of an inner {@code @List} annotation for
	 * multi-valued constraints if the actual constraint type is package private. Thus the multi-value annotation is a
	 * top-level type itself as workaround here.
	 * <p>
	 * This is a limitation of how proxies for annotations are generated by the JDK.
	 */
	@Test
	public void shouldValidatePackagePrivateMultiValueConstraint() {
		Set<ConstraintViolation<PolarBear>> violations = validator.validate( new PolarBear() );
		assertEquals( violations.size(), 1 );
		assertEquals(
				violations.iterator().next().getConstraintDescriptor().getAnnotation().annotationType(),
				ValidAnimalName.class
		);
	}
}
