content: /*
   *  Licensed to the Apache Software Foundation (ASF) under one
   *  or more contributor license agreements.  See the NOTICE file
   *  distributed with this work for additional information
   *  regarding copyright ownership.  The ASF licenses this file
   *  to you 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.apache.causeway.testing.fakedata.applib.services;
  
  import java.net.URL;
  import java.sql.Timestamp;
  import java.time.Instant;
  import java.time.LocalDate;
  import java.time.OffsetDateTime;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collection;
  import java.util.Date;
  import java.util.Set;
  import java.util.UUID;
  import java.util.function.Predicate;
  
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.mockito.Mockito;
  
  import static org.assertj.core.api.Assertions.assertThat;
  
  import org.apache.causeway.applib.clock.VirtualClock;
  import org.apache.causeway.applib.services.clock.ClockService;
  import org.apache.causeway.applib.services.repository.RepositoryService;
  import org.apache.causeway.applib.value.Blob;
  import org.apache.causeway.applib.value.Clob;
  import org.apache.causeway.applib.value.Password;
  import org.apache.causeway.commons.internal.collections._Lists;
  import org.apache.causeway.commons.internal.collections._Sets;
  
  class FakeDataServiceTest {
  
      FakeDataService fakeDataService;
      RepositoryService mockRepositoryService = Mockito.mock(RepositoryService.class);
      ClockService mockClockService = Mockito.mock(ClockService.class);
  
      @BeforeEach
      public void setUp() throws Exception {
          fakeDataService = new FakeDataService(mockClockService, mockRepositoryService);
          fakeDataService.init();
  
          final VirtualClock virtualClock = VirtualClock.frozenAt(Instant.now());
          Mockito.when(mockClockService.getClock()).thenReturn(virtualClock);
      }
  
      public static class CausewayBlobsTest extends FakeDataServiceTest {
  
          CausewayBlobs causewayBlobs;
  
          @Override
          @BeforeEach
          public void setUp() throws Exception {
              super.setUp();
              causewayBlobs = fakeDataService.causewayBlobs();
          }
  
          @Test
          public void any() throws Exception {
  
              final Blob blob = causewayBlobs.any();
  
              assertThat(blob).isNotNull();
              assertThat(blob.getName()).isNotNull();
              assertThat(blob.getBytes()).isNotNull();
              assertThat(blob.getBytes().length).isGreaterThan(0);
              assertThat(blob.getMimeType()).isNotNull();
          }
  
          @Test
          public void anyJpg() throws Exception {
  
              final Blob blob = causewayBlobs.anyJpg();
  
              assertThat(blob).isNotNull();
              assertThat(blob.getName()).endsWith(".jpg");
              assertThat(blob.getBytes()).isNotNull();
              assertThat(blob.getBytes().length).isGreaterThan(0);
              assertThat(blob.getMimeType().toString()).isEqualTo("image/jpeg");
          }
  
          @Test
          public void anyPdf() throws Exception {
  
              final Blob blob = causewayBlobs.anyPdf();
  
              assertThat(blob).isNotNull();
              assertThat(blob.getName()).endsWith(".pdf");
              assertThat(blob.getBytes()).isNotNull();
              assertThat(blob.getBytes().length).isGreaterThan(0);
              assertThat(blob.getMimeType().toString()).isEqualTo("application/pdf");
          }
  
      }
  
      public static class CausewayClobsTest extends FakeDataServiceTest {
  
          CausewayClobs causewayClobs;
  
          @Override
          @BeforeEach
          public void setUp() throws Exception {
              super.setUp();
              causewayClobs = fakeDataService.causewayClobs();
          }
  
          @Test
          public void any() throws Exception {
  
              final Clob clob = causewayClobs.any();
  
              assertThat(clob).isNotNull();
              assertThat(clob.getName()).isNotNull();
              assertThat(clob.getChars()).isNotNull();
              assertThat(clob.getChars().length()).isGreaterThan(0);
              assertThat(clob.getMimeType()).isNotNull();
          }
  
          @Test
          public void anyRtf() throws Exception {
  
              final Clob clob = causewayClobs.anyRtf();
  
              assertThat(clob).isNotNull();
              assertThat(clob.getName()).endsWith(".rtf");
              assertThat(clob.getChars()).isNotNull();
              assertThat(clob.getChars().length()).isGreaterThan(0);
              assertThat(clob.getMimeType().toString()).isEqualTo("application/rtf");
          }
  
          @Test
          public void anyXml() throws Exception {
  
              final Clob clob = causewayClobs.anyXml();
  
              assertThat(clob).isNotNull();
              assertThat(clob.getName()).endsWith(".xml");
              assertThat(clob.getChars()).isNotNull();
              assertThat(clob.getChars().length()).isGreaterThan(0);
              assertThat(clob.getMimeType().toString()).isEqualTo("text/xml");
          }
  
      }
  
      @Test
      public void bytes_upTo() throws Exception {
          final byte b = fakeDataService.bytes().upTo((byte) 10);
          assertThat(b).isLessThan((byte)10);
      }
  
      @Test
      public void shorts_upTo() throws Exception {
          final short s = fakeDataService.shorts().upTo((short) 10);
          assertThat(s).isLessThan((short)10);
      }
  
      @Test
      public void ints_upTo() throws Exception {
          final int i = fakeDataService.ints().upTo(10);
          assertThat(i).isLessThan(10);
      }
  
      @Test
      public void strings_fixed() throws Exception {
          final String str = fakeDataService.strings().fixed(12);
          assertThat(str.length()).isEqualTo(12);
      }
  
      @Test
      public void strings_upper() throws Exception {
          final String str = fakeDataService.strings().upper(8);
          assertThat(str.length()).isEqualTo(8);
          assertThat(str).matches("[A-Z]{8}");
      }
  
      @Test
      public void passwords_any() throws Exception {
          final Password pwd = fakeDataService.causewayPasswords().any();
          assertThat(pwd.getPassword()).isNotNull();
          assertThat(pwd.getPassword().length()).isEqualTo(12);
      }
  
      @Test
      public void jodaDateTimes_any() throws Exception {
          final OffsetDateTime any = fakeDataService.javaTimeDateTimes().any();
          assertThat(any).isNotNull();
      }
  
      @Test
      public void jodaLocalDates_any() throws Exception {
          final LocalDate any = fakeDataService.javaTimeLocalDates().any();
          assertThat(any).isNotNull();
      }
  
      @Test
      public void javaUtilDates_any() throws Exception {
          final Date any = fakeDataService.javaUtilDates().any();
          assertThat(any).isNotNull();
      }
  
      @Test
      public void javaSqlDates_any() throws Exception {
          final java.sql.Date any = fakeDataService.javaSqlDates().any();
          assertThat(any).isNotNull();
      }
  
      @Test
      public void javaSqlTimestamps_any() throws Exception {
          final Timestamp any = fakeDataService.javaSqlTimestamps().any();
          assertThat(any).isNotNull();
      }
  
      @Test
      public void urls_any() throws Exception {
          final URL any = fakeDataService.urls().any();
          assertThat(any).isNotNull();
      }
  
      @Test
      public void uuids_any() throws Exception {
          final UUID any = fakeDataService.uuids().any();
          assertThat(any).isNotNull();
      }
  
      public static class CollectionsTest extends FakeDataServiceTest {
  
          @Test
          public void anyOfObject() throws Exception {
  
             final Set<Object> seen = _Sets.newHashSet();
             final ArrayList<Object> ints = _Lists.newArrayList(Arrays.asList(new Object(), new Object(), new Object()));
  
             for (int i = 0; i < 1000; i++) {
                 final Object rand = fakeDataService.collections().anyOf(ints);
                  seen.add(rand);
             }
  
             ints.removeAll(seen);
  
             assertThat(ints).isEmpty();
          }
  
          @Test
          public void anyOfObjectExcept() throws Exception {
  
              final Object thisOne = new Object();
              final Set<Object> seen = _Sets.newHashSet();
              final Collection<Object> ints = _Lists.newArrayList(Arrays.asList(new Object(), thisOne, new Object()));
  
              for (int i = 0; i < 1000; i++) {
                  final Object rand = fakeDataService.collections().anyOfExcept(ints, (Predicate<Object>) obj -> obj == thisOne);
                  seen.add(rand);
              }
  
              ints.removeAll(seen);
  
              assertThat(ints).hasSize(1);
              assertThat(ints.iterator().next()).isEqualTo(thisOne);
          }
  
          @Test
          public void anyInt() throws Exception {
  
             final Set<Integer> seen = _Sets.newHashSet();
             final Collection<Integer> ints = _Lists.newArrayList(Arrays.asList(1, 2, 3, 4));
  
             for (int i = 0; i < 1000; i++) {
                 final int rand = fakeDataService.collections().anyOf(ints);
                  seen.add(rand);
             }
  
             ints.removeAll(seen);
  
             assertThat(ints).isEmpty();
          }
  
          @Test
          public void anyIntExcept() throws Exception {
  
             final Set<Integer> seen = _Sets.newHashSet();
             final Collection<Integer> ints = _Lists.newArrayList(Arrays.asList(1, 2, 3, 4));
  
             for (int i = 0; i < 1000; i++) {
                 final int rand = fakeDataService.collections().anyOfExcept(ints, (Predicate<Integer>) integer -> integer == 2);
                  seen.add(rand);
             }
  
             ints.removeAll(seen);
  
             assertThat(ints).hasSize(1);
             assertThat(ints.iterator().next()).isEqualTo(2);
          }
  
      }
  
  }
  