Fixing bad char issue and adding new tests to catch

This commit is contained in:
Jason House
2020-07-30 15:06:18 +09:00
parent fd6f94c124
commit f9e3bfd18f
11 changed files with 172 additions and 40 deletions
@@ -14,9 +14,13 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.jasonhhouse.gaps.json.MovieDeserializer;
import com.jasonhhouse.gaps.json.MovieSerializer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -142,6 +146,10 @@ public final class Movie implements Comparable<Movie> {
return moviesInCollection;
}
public @NotNull String getNameWithoutBadCharacters() {
return nameWithoutBadCharacters;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -170,7 +178,7 @@ public final class Movie implements Comparable<Movie> {
@Override
public int hashCode() {
return Objects.hash(name, year);
return Objects.hash(nameWithoutBadCharacters, year);
}
@Nullable
@@ -183,18 +191,20 @@ public final class Movie implements Comparable<Movie> {
return "Movie{" +
"name='" + name + '\'' +
", year=" + year +
", nameWithoutBadCharacters='" + nameWithoutBadCharacters + '\'' +
", posterUrl='" + posterUrl + '\'' +
", collection='" + collection + '\'' +
", collectionId=" + collectionId +
", tvdbId=" + tvdbId +
", imdbId='" + imdbId + '\'' +
", language='" + language + '\'' +
", overview='" + overview + '\'' +
", collection='" + collection + '\'' +
", collectionId=" + collectionId +
", tvdbId=" + tvdbId +
", moviesInCollection=" + moviesInCollection +
'}';
}
public int compareTo(Movie o) {
return getName().compareTo(o.getName());
return getNameWithoutBadCharacters().compareTo(o.getNameWithoutBadCharacters());
}
public static class Builder {
@@ -24,21 +24,20 @@ import com.jasonhhouse.gaps.SearchCancelledException;
import com.jasonhhouse.gaps.SearchResults;
import com.jasonhhouse.gaps.UrlGenerator;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@@ -154,7 +153,7 @@ public class GapsSearchService implements GapsSearch {
@Override
public void cancelSearch() {
LOGGER.debug("cancelSearch()");
LOGGER.info("cancelSearch()");
cancelSearch.set(true);
}
@@ -277,8 +276,8 @@ public class GapsSearchService implements GapsSearch {
}
if (results.size() > 1) {
LOGGER.debug("Results for " + movie + " came back with " + results.size() + " results. Using first result.");
LOGGER.debug(movie + " URL: " + searchMovieUrl);
LOGGER.info("Results for " + movie + " came back with " + results.size() + " results. Using first result.");
LOGGER.info(movie + " URL: " + searchMovieUrl);
}
JsonNode result = results.get(0);
@@ -287,7 +286,7 @@ public class GapsSearchService implements GapsSearch {
int indexOfMovie = everyMovie.indexOf(movie);
if (indexOfMovie != -1) {
LOGGER.debug("Merging movie data");
LOGGER.info("Merging movie data");
everyMovie.get(indexOfMovie).setTvdbId(movie.getTvdbId());
} else {
Movie newMovie = new Movie.Builder(movie.getName(), movie.getYear())
@@ -369,7 +368,7 @@ public class GapsSearchService implements GapsSearch {
int indexOfMovie = everyMovie.indexOf(movie);
if (indexOfMovie != -1) {
LOGGER.debug("Merging movie data");
LOGGER.info("Merging movie data");
everyMovie.get(indexOfMovie).setTvdbId(movie.getTvdbId());
everyMovie.get(indexOfMovie).setCollectionId(movie.getCollectionId());
everyMovie.get(indexOfMovie).setCollection(movie.getCollection());
@@ -425,19 +424,32 @@ public class GapsSearchService implements GapsSearch {
JsonNode parts = collection.get("parts");
parts.iterator().forEachRemaining(jsonNode -> {
String title = jsonNode.get("title").asText();
int year = -1;
if(jsonNode.has("year")) {
year = jsonNode.get("year").asInt(-1);
int year = 0;
if (jsonNode.has("release_date")) {
String oldDate = jsonNode.get("release_date").asText("0000-01-01");
try {
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(oldDate);
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
year = calendar.get(Calendar.YEAR);
} catch (ParseException e) {
LOGGER.warn("Could not parse date");
}
}
String id = jsonNode.get("id").asText();
Boolean owned = ownedMovies.contains(new Movie.Builder(title, year).build());
Movie collectionMovie = new Movie.Builder(title, year).build();
LOGGER.info(collectionMovie.toString());
Boolean owned = ownedMovies.contains(collectionMovie);
moviesInCollection.add(new MovieFromCollection(title, id, owned));
});
}
LOGGER.info("MoviesInCollection: " + Arrays.toString(moviesInCollection.toArray()));
if (indexOfMovie != -1) {
if (indexOfMovie != -1) {
int id = collection.get("id").asInt(-1);
String name = collection.get("name").asText();
everyMovie.get(indexOfMovie).setCollectionId(id);
@@ -485,7 +497,7 @@ public class GapsSearchService implements GapsSearch {
try {
posterUrl = part.get("poster_url").asText();
} catch (Exception e) {
LOGGER.debug("No poster found for" + title + ".");
LOGGER.info("No poster found for" + title + ".");
}
Movie movieFromCollection = new Movie.Builder(title, year)
@@ -496,21 +508,27 @@ public class GapsSearchService implements GapsSearch {
.setMoviesInCollection(moviesInCollection)
.build();
Movie ownedMovieFromCollection = new Movie.Builder(title, year).build();
if (ownedMovies.contains(movieFromCollection)) {
LOGGER.info("Skip owned movie: " + movieFromCollection);
continue;
}
indexOfMovie = everyMovie.indexOf(new Movie.Builder(title, year).build());
indexOfMovie = everyMovie.indexOf(movieFromCollection);
if (indexOfMovie == -1) {
LOGGER.debug("Adding collection movie");
LOGGER.info("Adding collection movie");
everyMovie.add(movieFromCollection);
} else {
LOGGER.debug("Merging collection movie");
LOGGER.info("Merging collection movie");
everyMovie.get(indexOfMovie).setTvdbId(tvdbId);
}
if (ownedMovies.contains(ownedMovieFromCollection)) {
if (ownedMovies.contains(movieFromCollection)) {
LOGGER.info("Owned movie found: " + movieFromCollection);
searched.add(movieFromCollection);
sendEmptySearchUpdate(ownedMovies.size(), searchedMovieCount);
} else if (!searched.contains(movieFromCollection) && year != 0 && year < Year.now().getValue()) {
LOGGER.info("Missing movie found: " + movieFromCollection);
// Get recommended Movie details from MovieDB API
HttpUrl movieDetailUrl = urlGenerator.generateMovieDetailUrl(gapsService.getPlexSearch().getMovieDbApiKey(), String.valueOf(movieFromCollection.getTvdbId()), languageCode);
@@ -560,6 +578,14 @@ public class GapsSearchService implements GapsSearch {
.setMoviesInCollection(moviesInCollection)
.build();
LOGGER.info("ownedMovies");
ownedMovies.forEach(movie1 -> LOGGER.info(movie1.toString()));
if (ownedMovies.contains(recommendedMovie)) {
LOGGER.info("Skip owned movie: " + recommendedMovie);
continue;
}
if (recommended.add(recommendedMovie)) {
// Write current list of recommended movies to file.
ioService.writeRssFile(machineIdentifier, key, recommended);
@@ -218,7 +218,7 @@ public class IoService {
fullFile.append(line);
}
return objectMapper.readValue(fullFile.toString(), new TypeReference<List<Movie>>() {
return objectMapper.readValue(fullFile.toString(), new TypeReference<>() {
});
} catch (FileNotFoundException e) {
LOGGER.error("Can't find file " + ownedMovieFile, e);
@@ -392,7 +392,7 @@ public class PlexQueryImpl implements PlexQuery {
ownedMovies.add(movie);
}
LOGGER.debug(ownedMovies.size() + " movies found in plex");
LOGGER.info(ownedMovies.size() + " movies found in plex");
} catch (IOException e) {
String reason = "Error connecting to Plex to get Movie list: " + url;
+20 -1
View File
@@ -15,7 +15,7 @@ export function spyOnAddEventListener(win) {
};
}
export function searchPlexForMovies(cy) {
export function searchPlexForMoviesFromSaw(cy) {
cy.get('#dropdownMenuLink')
.click();
@@ -33,6 +33,25 @@ export function searchPlexForMovies(cy) {
.should('have.text', 'Showing 1 to 1 of 1 entries');
}
export function searchPlexForMoviesFromMovies(cy) {
cy.get('#dropdownMenuLink')
.click();
cy.get('[data-key="1"]')
.click();
cy.get('.card-body > .btn')
.click();
cy.get('label > input')
.clear()
.type('2001 A Space');
cy.get('#movies_info')
.should('have.text', 'Showing 1 to 1 of 1 entries (filtered from 4 total entries)');
}
export function nuke() {
cy.request('PUT', '/nuke')
.then((response) => {
+2 -2
View File
@@ -1,4 +1,4 @@
import {nuke, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
import {nuke, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
describe('Library API', function () {
@@ -53,7 +53,7 @@ describe('Plex Movie List API', function () {
function searchSawLibrary(cy) {
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
searchPlexForMovies(cy);
searchPlexForMoviesFromSaw(cy);
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
}
@@ -1,4 +1,4 @@
import {jokerLibraryBefore, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
import {jokerLibraryBefore, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
describe('Find owned movies', function () {
before(redLibraryBefore);
@@ -6,7 +6,7 @@ describe('Find owned movies', function () {
it('Find Movies', () => {
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
searchPlexForMovies(cy);
searchPlexForMoviesFromSaw(cy);
});
it('Refresh Movies', () => {
+2 -2
View File
@@ -1,4 +1,4 @@
import {nuke, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
import {nuke, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
describe('Recommended API', function () {
@@ -30,7 +30,7 @@ describe('Recommended API', function () {
function searchSawLibrary(cy) {
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
searchPlexForMovies(cy);
searchPlexForMoviesFromSaw(cy);
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
}
@@ -0,0 +1,77 @@
import {redLibraryBefore, searchPlexForMoviesFromMovies, spyOnAddEventListener} from "../common";
describe('Search for Recommended Best Movies', function () {
beforeEach(redLibraryBefore);
it('Clean configuration page load', () => {
searchMoviesLibrary(cy);
cy.get('#libraryTitle').then( ($libraryTitle) => {
if($libraryTitle.text() !== "Movies") {
cy.get('#dropdownMenuLink')
.click();
cy.get('[data-key="1"]')
.click();
}
});
cy.get('#noMovieContainer > .card > .card-img-top')
.should('not.be.visible');
});
it('Search Movies with bad chars', () => {
searchMoviesLibrary(cy);
cy.get('#dropdownMenuLink')
.click();
cy.get('[data-key="1"]')
.click();
cy.get('.card-body > .btn')
.click();
cy.wait(5000);
cy.get('#movies_info')
.should('have.text', 'Showing 1 to 7 of 7 entries');
});
it('Research Movies with bad chars', () => {
searchMoviesLibrary(cy);
cy.get('#dropdownMenuLink')
.click();
cy.get('[data-key="1"]')
.click();
cy.get('.card-body > .btn')
.click();
cy.wait(5000);
cy.get('#movies_info')
.should('have.text', 'Showing 1 to 7 of 7 entries');
cy.get('#movieContainer > [onclick="searchForMovies()"]')
.click();
cy.wait(5000);
cy.get('#movies_info')
.should('have.text', 'Showing 1 to 7 of 7 entries');
cy.get(':nth-child(1) > td > .card > .row > .col-md > .card-body > h5.card-title')
.should('have.text', '2010 (1984)');
});
});
function searchMoviesLibrary(cy) {
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
searchPlexForMoviesFromMovies(cy);
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
}
@@ -1,4 +1,4 @@
import {redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
import {redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
describe('Search for Recommended', function () {
beforeEach(redLibraryBefore);
@@ -66,7 +66,7 @@ describe('Search for Recommended', function () {
function searchSawLibrary(cy) {
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
searchPlexForMovies(cy);
searchPlexForMoviesFromSaw(cy);
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
}
+2 -2
View File
@@ -1,4 +1,4 @@
import {nuke, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
import {nuke, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
describe('Searched RSS', function () {
before(nuke)
@@ -35,7 +35,7 @@ describe('Searched RSS', function () {
function searchSawLibrary(cy) {
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
searchPlexForMovies(cy);
searchPlexForMoviesFromSaw(cy);
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
}