diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingRegattaORCCertificateAssignmentEvent.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingRegattaORCCertificateAssignmentEvent.java new file mode 100644 index 00000000000..38f6f97d1e6 --- /dev/null +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingRegattaORCCertificateAssignmentEvent.java @@ -0,0 +1,133 @@ +package com.sap.sailing.mongodb.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Serializable; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bson.Document; +import org.json.simple.parser.ParseException; +import org.junit.Before; +import org.junit.Test; + +import com.mongodb.MongoException; +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; +import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCCertificateAssignmentEventImpl; +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.DomainFactory; +import com.sap.sailing.domain.base.impl.CompetitorImpl; +import com.sap.sailing.domain.orc.ORCCertificateImporter; +import com.sap.sailing.domain.orc.impl.ORCCertificateImporterJSON; +import com.sap.sailing.domain.persistence.PersistenceFactory; +import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl; +import com.sap.sailing.domain.persistence.impl.FieldNames; +import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl; +import com.sap.sailing.domain.racelog.RaceLogIdentifier; +import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory; +import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; +import com.sap.sse.common.Speed; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +/** + * @author Daniel Lisunkin (i505543) + */ +public class TestStoringAndLoadingRegattaORCCertificateAssignmentEvent extends AbstractMongoDBTest { + + public TestStoringAndLoadingRegattaORCCertificateAssignmentEvent() throws UnknownHostException, MongoException { + super(); + } + + protected TimePoint expectedEventTime = new MillisecondsTimePoint(750); + protected Serializable expectedId = UUID.randomUUID(); + protected List expectedInvolvedBoats = Collections.emptyList(); + protected int expectedPassId = 42; + private AbstractLogEventAuthor author = new LogEventAuthorImpl("Test Author", 1); + private final Competitor competitor = new CompetitorImpl("comp", "Comp", "KYC", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null); + + protected MongoObjectFactoryImpl mongoFactory = (MongoObjectFactoryImpl) PersistenceFactory.INSTANCE + .getMongoObjectFactory(getMongoService(), new MockSmartphoneImeiServiceFinderFactory()); + protected DomainObjectFactoryImpl domainFactory = (DomainObjectFactoryImpl) PersistenceFactory.INSTANCE + .getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE, + new MockSmartphoneImeiServiceFinderFactory()); + + protected RaceLogIdentifier logIdentifier; + private ORCCertificateImporter importer; + + @Before + public void setUp() throws FileNotFoundException, IOException, ParseException { + logIdentifier = mock(RaceLogIdentifier.class); + when(logIdentifier.getIdentifier()).thenReturn( + new com.sap.sse.common.Util.Triple("a", "b", UUID.randomUUID().toString())); + DomainFactory.INSTANCE.getCompetitorAndBoatStore().clearCompetitors(); + importer = new ORCCertificateImporterJSON(new FileInputStream(new File("resources/GER2019.json"))); + } + + @Test + public void test() throws JsonDeserializationException, ParseException { + RaceLogORCCertificateAssignmentEvent expectedEvent = new RaceLogORCCertificateAssignmentEventImpl(MillisecondsTimePoint.now(), expectedEventTime, author, + expectedId, expectedPassId, importer.getCertificate("GER 5549"), competitor); + + Document dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent); + RaceLogORCCertificateAssignmentEvent actualEvent = loadEvent(dbObject); + + assertBaseFields(expectedEvent, actualEvent); + assertEquals(expectedEvent.getCompetitorID(), actualEvent.getCompetitorID()); + assertEquals(expectedEvent.getCertificate().getSailnumber(), actualEvent.getCertificate().getSailnumber()); + assertEquals(expectedEvent.getCertificate().getGPH(), actualEvent.getCertificate().getGPH(), 0.00001); + + List expectedBeatVMGPredictions = new ArrayList<>(expectedEvent.getCertificate().getBeatVMGPredictions().values()); + List expectedBeatVMGPredictionsInKnots = expectedBeatVMGPredictions.stream().map(s -> s.getKnots()).collect(Collectors.toList()); + List actualBeatVMGPredictions = new ArrayList<>(actualEvent.getCertificate().getBeatVMGPredictions().values()); + List actualBeatVMGPredictionsInKnots = actualBeatVMGPredictions.stream().map(s -> s.getKnots()).collect(Collectors.toList()); + // Unfortunately we can't assure that the speeds have the same type and therefore we can't assure the same level of accuracy after possible conversions. + // A normal comparison of the two HashMaps containing the values doesn't address this issue, so we need to compare the double values (in Knots) to ensure + // the same level of accuracy. + assertEquals(expectedBeatVMGPredictionsInKnots, actualBeatVMGPredictionsInKnots); + } + + public void assertBaseFields(RaceLogEvent expectedEvent, RaceLogEvent actualEvent) { + assertNotNull(actualEvent); + assertEquals(expectedEvent.getCreatedAt(), actualEvent.getCreatedAt()); + assertEquals(expectedEvent.getLogicalTimePoint(), actualEvent.getLogicalTimePoint()); + assertEquals(expectedEvent.getId(), actualEvent.getId()); + assertEquals(expectedEvent.getInvolvedCompetitors().size(), Util.size(actualEvent.getInvolvedCompetitors())); + assertEquals(expectedEvent.getPassId(), actualEvent.getPassId()); + } + + /** + * Will always wait a couple of milliseconds to ensure that {@link RaceLogEvent#getCreatedAt()} has passed. + * @throws ParseException + * @throws JsonDeserializationException + */ + @SuppressWarnings("unchecked") + private T loadEvent(Document dbObject) throws JsonDeserializationException, ParseException { + try { + Thread.sleep(2); + } catch (InterruptedException ie) { + fail(ie.toString()); + } + RaceLogEvent dbEvent = domainFactory.loadRaceLogEvent((Document) dbObject.get(FieldNames.RACE_LOG_EVENT.name())).getA(); + T actualEvent = (T) dbEvent; + return actualEvent; + } + +}