public static final Person testPerson = new Person(); public static Date testPersonChangesEndDate; public static Date testPersonChangesStartDate; public static void assertImages(List<Image> images) {
    assertThat(images).isNotNull();
    assertThat(images).isNotEmpty();
    for (Image image : images) {
        assertImage(image);
    }
} public static void assertTaggedImages(TaggedImagesResultsPage images) {
    assertBaseResultsPage(images);

    for (TaggedImage image : images.results) {
        assertTaggedImage(image);
    }
} public static void assertPerson(Person person) {
    assertBasePerson(person);
    assertThat(person.biography).isNotNull();
    assertThat(person.birthday).isNotNull();
    assertThat(person.gender).isNotNull();
    assertThat(person.imdb_id).isNotNull();
    assertThat(person.place_of_birth).isNotNull();
    assertThat(person.also_known_as).isNotNull();
} public static void assertPersonCredits(PersonCredits credits) {
    assertThat(credits).isNotNull();
    assertPersonCastCredits(credits.cast);
    assertPersonCrewCredits(credits.crew);
} public static void assertPersonDataIntegrity(Person person) {
    assertPerson(person);
    assertThat(person.name).isEqualTo(TestData.testPerson.name);
    assertThat(person.birthday).isEqualTo(TestData.testPerson.birthday);
    assertThat(person.id).isEqualTo(TestData.testPerson.id);
    assertThat(person.imdb_id).isEqualTo(TestData.testPerson.imdb_id);
    assertThat(person.gender).isEqualTo(TestData.testPerson.gender);
    assertThat(person.adult).isEqualTo(TestData.testPerson.adult);
    assertThat(person.place_of_birth).isEqualTo(TestData.testPerson.place_of_birth);

} public static void assertPersonResultsPage(PersonResultsPage personResultsPage) {
    assertBaseResultsPage(personResultsPage);
    for (BasePerson basePerson : personResultsPage.results) {
        assertBasePerson(basePerson);
    }
} public abstract class BaseTestCase {

    private static final boolean LOG_BODY = System.getenv("CI") == null;

    // Do NOT use this API key in your application, it is only for testing tmdb-java!
    private static final String TEST_API_KEY = "25da90e9f8f0b3892d8bdeb6c3d6267d";
    // limit requests for tests to avoid hitting TMDb rate limit (40 requests/10 seconds)
    @SuppressWarnings("UnstableApiUsage") private static final RateLimiter rateLimiter = RateLimiter.create(5);

    private static final Tmdb unauthenticatedInstance = new BaseTestCase.TestTmdb(TEST_API_KEY);
    private static final Tmdb authenticatedInstance  = new BaseTestCase.TestTmdb(TEST_API_KEY);

    protected static Tmdb getUnauthenticatedInstance() {
        return unauthenticatedInstance;
    }

    protected static Tmdb getAuthenticatedInstance() {
        return authenticatedInstance;
    }

    private static class TestTmdb extends Tmdb {
        public TestTmdb(String apiKey) {
            super(apiKey);
        }

        @Override
        protected void setOkHttpClientDefaults(OkHttpClient.Builder builder) {
            final Tmdb instance = this;
            builder.authenticator(new TmdbAuthenticator(instance));
            builder.addInterceptor(chain -> {
                rateLimiter.acquire();
                return TmdbInterceptor.handleIntercept(chain, instance);
            });
            // add logging, standard output is easier to read
            // but only log headers on CI to keep logs short
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor(System.out::println);
            logging.setLevel(LOG_BODY ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.BASIC);
            builder.addNetworkInterceptor(logging);
        }
    }

} public class PersonAssertions {
    public static void assertBasePerson(BasePerson person) {
        assertBasePerson(person, true);
    }

    public static void assertBasePerson(BasePerson person, Boolean extensive) {
        assertThat(person).isNotNull();
        assertThat(person.id).isPositive();
        assertThat(person.name).isNotNull();

        if (!extensive)
            return;

        assertThat(person.adult).isNotNull();
        if (person.popularity != null) {
            assertThat(person.popularity).isPositive();
        }
        try {
            Person p = (Person) person;
        } catch (Exception exc) {
            assertThat(person.known_for).isNotNull();
            for (Media media : person.known_for) {
                assertMedia(media);
            }
        }
    }

    public static void assertPerson(Person person) {
        assertBasePerson(person);
        assertThat(person.biography).isNotNull();
        assertThat(person.birthday).isNotNull();
        assertThat(person.gender).isNotNull();
        assertThat(person.imdb_id).isNotNull();
        assertThat(person.place_of_birth).isNotNull();
        assertThat(person.also_known_as).isNotNull();
    }


    public static void assertPersonDataIntegrity(Person person) {
        assertPerson(person);
        assertThat(person.name).isEqualTo(TestData.testPerson.name);
        assertThat(person.birthday).isEqualTo(TestData.testPerson.birthday);
        assertThat(person.id).isEqualTo(TestData.testPerson.id);
        assertThat(person.imdb_id).isEqualTo(TestData.testPerson.imdb_id);
        assertThat(person.gender).isEqualTo(TestData.testPerson.gender);
        assertThat(person.adult).isEqualTo(TestData.testPerson.adult);
        assertThat(person.place_of_birth).isEqualTo(TestData.testPerson.place_of_birth);

    }

    public static void assertTestPersonExternalIds(PersonExternalIds ids) {
        assertThat(ids.imdb_id).isEqualTo(testPerson.imdb_id);
    }

    public static void assertPersonResultsPage(PersonResultsPage personResultsPage) {
        assertBaseResultsPage(personResultsPage);
        for (BasePerson basePerson : personResultsPage.results) {
            assertBasePerson(basePerson);
        }
    }

    public static void assertPersonCredits(PersonCredits credits) {
        assertThat(credits).isNotNull();
        assertPersonCastCredits(credits.cast);
        assertPersonCrewCredits(credits.crew);
    }

    public static void assertPersonCastCredits(List<PersonCastCredit> credits) {
        assertThat(credits).isNotNull();
        assertThat(credits).isNotEmpty();
        for (PersonCastCredit credit : credits) {
            assertBasePersonCredit(credit);

            assertThat(credit.character).isNotNull();

            switch (credit.media.media_type) {
                case TV:
                    assertThat(credit.episode_count).isNotNull();
            }

        }
    }

    public static void assertPersonCrewCredits(List<PersonCrewCredit> credits) {
        assertThat(credits).isNotNull();
        assertThat(credits).isNotEmpty();
        for (PersonCrewCredit credit : credits) {
            assertBasePersonCredit(credit);

            assertThat(credit.job).isNotNull();
            assertThat(credit.department).isNotNull();
        }
    }


    public static void assertBasePersonCredit(BasePersonCredit credit) {
        assertThat(credit.media.media_type).isNotNull();
        assertThat(credit.credit_id).isNotNull();
        assertThat(credit.media).isNotNull();
        switch (credit.media.media_type) {
            case MOVIE:
                assertThat(credit.media.movie).isNotNull();
                assertThat(credit.media.movie.id).isNotNull();
                assertThat(credit.media.movie.title).isNotNull();
                assertThat(credit.media.movie.original_title).isNotNull();
                break;
            case TV:
                assertThat(credit.media.tvShow).isNotNull();
                assertThat(credit.media.tvShow.id).isNotNull();
                assertThat(credit.media.tvShow.name).isNotNull();
                assertThat(credit.media.tvShow.original_name).isNotNull();
                break;
        }
    }
} public class Person extends BasePerson {

    public List<JsonPrimitive> also_known_as;
    public String biography;
    public Date birthday;
    public Date deathday;
    public Integer gender;
    public String homepage;
    public String imdb_id;
    public String place_of_birth;

    public PersonExternalIds external_ids;
    public PersonCredits combined_credits;
    public PersonCredits movie_credits;
    public PersonCredits tv_credits;
    public PersonImages images;
    public TaggedImagesResultsPage tagged_images;
    public Changes changes;

} public class PersonCredits {

    public Integer id;
    public List<PersonCastCredit> cast;
    public List<PersonCrewCredit> crew;

} public class PersonExternalIds {

    public Integer id;
    public String imdb_id;
    public String facebook_id;
    public String freebase_id;
    public String freebase_mid;
    public Integer tvrage_id;
    public String instagram_id;
    public String twitter_id;

} public class PersonImages {

    public Integer id;
    public List<Image> profiles;

} public class TmdbDate {

    // can not use ThreadLocal.withInitial as it requires Java 8
    private static final ThreadLocal<DateFormat> TMDB_DATE_FORMAT = new ThreadLocal<DateFormat>() {
        @Override
        public DateFormat initialValue() {
            return new SimpleDateFormat(TmdbHelper.TMDB_DATE_PATTERN);
        }
    };

    private final Date date;

    public TmdbDate(Date date) {
        this.date = date;
    }

    public TmdbDate(String date) {
        Date parsedDate;
        try {
            parsedDate = TMDB_DATE_FORMAT.get().parse(date);
        } catch (ParseException e) {
            parsedDate = null;
        }
        this.date = parsedDate;
    }

    @Override
    public String toString() {
        return TMDB_DATE_FORMAT.get().format(date);
    }

} public enum AppendToResponseItem {
    // Applies to Movies, TV Shows, TV Episodes, TV Seasons, People, Collections
    IMAGES("images"),

    // Applies to Movies, TV Shows, TV Episodes, TV Seasons, People
    CHANGES("changes"),

    // Applies to Movies, TV Shows, TV Episodes, TV Seasons
    CREDITS("credits"),
    VIDEOS("videos"),

    // Applies to Movies, TV Shows
    ALTERNATIVE_TITLES("alternative_titles"),
    KEYWORDS("keywords"),
    RECOMMENDATIONS("recommendations"),
    RELEASE_DATES("release_dates"),
    REVIEWS("reviews"),
    SIMILAR("similar"),
    TRANSLATIONS("translations"),

    // Applies to Movies
    LISTS("lists"),

    // Applies to Movies, TV Shows, TV Episodes, TV Seasons, People
    EXTERNAL_IDS("external_ids"),

    // Applies to TV Shows
    CONTENT_RATINGS("content_ratings"),

    // Applies to People
    MOVIE_CREDITS("movie_credits"),
    TV_CREDITS("tv_credits"),
    COMBINED_CREDITS("combined_credits"),
    TAGGED_IMAGES("tagged_images"),

    // Applies to Keywords, Companies
    MOVIES("movies");

    private final String value;

    AppendToResponseItem(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return value;
    }
}
import static com.uwetrottmann.tmdb2.TestData.testPerson;
import static com.uwetrottmann.tmdb2.TestData.testPersonChangesEndDate;
import static com.uwetrottmann.tmdb2.TestData.testPersonChangesStartDate;
import static com.uwetrottmann.tmdb2.assertions.ChangeAssertions.assertContentChanges;
import static com.uwetrottmann.tmdb2.assertions.GenericAssertions.assertImages;
import static com.uwetrottmann.tmdb2.assertions.GenericAssertions.assertTaggedImages;
import static com.uwetrottmann.tmdb2.assertions.PersonAssertions.assertPerson;
import static com.uwetrottmann.tmdb2.assertions.PersonAssertions.assertPersonCredits;
import static com.uwetrottmann.tmdb2.assertions.PersonAssertions.assertPersonDataIntegrity;
import static com.uwetrottmann.tmdb2.assertions.PersonAssertions.assertPersonResultsPage;
import static org.assertj.core.api.Assertions.assertThat;
import com.uwetrottmann.tmdb2.BaseTestCase;
import com.uwetrottmann.tmdb2.assertions.PersonAssertions;
import com.uwetrottmann.tmdb2.entities.AppendToResponse;
import com.uwetrottmann.tmdb2.entities.Changes;
import com.uwetrottmann.tmdb2.entities.Person;
import com.uwetrottmann.tmdb2.entities.PersonCredits;
import com.uwetrottmann.tmdb2.entities.PersonExternalIds;
import com.uwetrottmann.tmdb2.entities.PersonImages;
import com.uwetrottmann.tmdb2.entities.PersonResultsPage;
import com.uwetrottmann.tmdb2.entities.TaggedImagesResultsPage;
import com.uwetrottmann.tmdb2.entities.TmdbDate;
import com.uwetrottmann.tmdb2.enumerations.AppendToResponseItem;
import java.io.IOException;
import java.util.HashMap;
import org.junit.Test;
import retrofit2.Call;
package com.uwetrottmann.tmdb2.services;



public class PeopleServiceTest extends BaseTestCase {

    @Test
    public void test_summary() throws IOException {
        Call<Person> call = getUnauthenticatedInstance().personService().summary(
                testPerson.id,
                null
        );

        Person person = call.execute().body();

        assertPerson(person);
    }

    @Test
    public void test_summary_with_append_to_response() throws IOException {
        HashMap<String, String> opts = new HashMap<>();
        opts.put("start_date", new TmdbDate(testPersonChangesStartDate).toString());
        opts.put("end_date", new TmdbDate(testPersonChangesEndDate).toString());

        Call<Person> call = getUnauthenticatedInstance().personService().summary(
                testPerson.id,
                null,
                new AppendToResponse(
                        AppendToResponseItem.IMAGES,
                        AppendToResponseItem.MOVIE_CREDITS,
                        AppendToResponseItem.COMBINED_CREDITS,
                        AppendToResponseItem.EXTERNAL_IDS,
                        AppendToResponseItem.CHANGES,
                        AppendToResponseItem.TAGGED_IMAGES,
                        AppendToResponseItem.TV_CREDITS
                ),
                opts
        );

        Person person = call.execute().body();

        assertPersonDataIntegrity(person);
        assertContentChanges(person.changes);
        assertImages(person.images.profiles);
        assertTaggedImages(person.tagged_images);
        assertPersonCredits(person.movie_credits);