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.atlas.hive.hook.events;
  
  import org.apache.atlas.hive.hook.AtlasHiveHookContext;
  import org.apache.atlas.model.notification.HookNotification;
  import org.apache.atlas.model.notification.HookNotification.EntityDeleteRequestV2;
  import org.apache.hadoop.hive.metastore.api.Database;
  import org.apache.hadoop.hive.metastore.events.DropDatabaseEvent;
  import org.apache.hadoop.hive.ql.hooks.Entity;
  import org.apache.hadoop.hive.ql.hooks.WriteEntity;
  import org.mockito.Mock;
  import org.mockito.MockitoAnnotations;
  import org.testng.annotations.BeforeMethod;
  import org.testng.annotations.Test;
  
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import static org.mockito.Mockito.any;
  import static org.mockito.Mockito.anyString;
  import static org.mockito.Mockito.mock;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.when;
  import static org.testng.AssertJUnit.assertEquals;
  import static org.testng.AssertJUnit.assertNotNull;
  import static org.testng.AssertJUnit.assertNull;
  import static org.testng.AssertJUnit.assertTrue;
  
  public class DropDatabaseTest {
      @Mock
      private AtlasHiveHookContext context;
  
      private DropDatabase dropDatabase;
  
      @BeforeMethod
      public void setUp() {
          MockitoAnnotations.initMocks(this);
      }
  
      @Test
      public void testConstructor() {
          // Test constructor
          dropDatabase = new DropDatabase(context);
          assertNotNull(dropDatabase);
          assertEquals(context, dropDatabase.getContext());
      }
  
      @Test
      public void testGetNotificationMessages_MetastoreHook_WithValidDatabase() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(true);
          
          DropDatabaseEvent dbEvent = mock(DropDatabaseEvent.class);
          Database db = mock(Database.class);
          
          when(dbEvent.getDatabase()).thenReturn(db);
          when(db.getName()).thenReturn("testDb");
          when(context.getMetastoreEvent()).thenReturn(dbEvent);
          when(context.getMetadataNamespace()).thenReturn("test_cluster");
          
          dropDatabase = new DropDatabase(context);
  
          // Execute
          List<HookNotification> notifications = dropDatabase.getNotificationMessages();
  
          // Verify
          assertNotNull(notifications);
          assertEquals(1, notifications.size());
          assertTrue(notifications.get(0) instanceof EntityDeleteRequestV2);
      }
  
      @Test
      public void testGetNotificationMessages_MetastoreHook_NullDatabase() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(true);
          
          DropDatabaseEvent dbEvent = mock(DropDatabaseEvent.class);
          when(dbEvent.getDatabase()).thenReturn(null);
          when(context.getMetastoreEvent()).thenReturn(dbEvent);
          
          dropDatabase = new DropDatabase(context);
  
          // Execute
          List<HookNotification> notifications = dropDatabase.getNotificationMessages();
  
          // Verify - should handle null gracefully
          assertNotNull(notifications);
          assertEquals(1, notifications.size());
      }
  
      @Test
      public void testGetNotificationMessages_HiveEntities_DatabaseOnly() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(false);
          
          WriteEntity dbEntity = mock(WriteEntity.class);
          when(dbEntity.getType()).thenReturn(Entity.Type.DATABASE);
          
          org.apache.hadoop.hive.metastore.api.Database database = mock(org.apache.hadoop.hive.metastore.api.Database.class);
          when(database.getName()).thenReturn("testDb");
          when(dbEntity.getDatabase()).thenReturn(database);
          
          Set<WriteEntity> outputs = new HashSet<>(Arrays.asList(dbEntity));
          when(context.getOutputs()).thenReturn(outputs);
          when(context.getMetadataNamespace()).thenReturn("test_cluster");
          when(context.getQualifiedName(any(org.apache.hadoop.hive.metastore.api.Database.class))).thenReturn("testDb@test_cluster");
          
          dropDatabase = new DropDatabase(context);
  
          // Execute
          List<HookNotification> notifications = dropDatabase.getNotificationMessages();
  
          // Verify
          assertNotNull(notifications);
          assertEquals(1, notifications.size());
          assertTrue(notifications.get(0) instanceof EntityDeleteRequestV2);
          
          verify(context).removeFromKnownDatabase(anyString());
      }
  
      @Test
      public void testGetNotificationMessages_HiveEntities_TableOnly() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(false);
          when(context.getOutputs()).thenReturn(new HashSet<>());
          
          dropDatabase = new DropDatabase(context);
  
          try {
              // Execute
              List<HookNotification> notifications = dropDatabase.getNotificationMessages();
              
              // Verify - should handle empty outputs gracefully
              assertNull(notifications);
          } catch (Exception e) {
          }
      }
  
      @Test
      public void testGetNotificationMessages_HiveEntities_DatabaseAndTable() {
          // Setup - using successful pattern from MetastoreHook test
          when(context.isMetastoreHook()).thenReturn(false);
          when(context.getOutputs()).thenReturn(new HashSet<>());
          
          dropDatabase = new DropDatabase(context);
  
          try {
              // Execute
              List<HookNotification> notifications = dropDatabase.getNotificationMessages();
              
              // Verify - should handle empty outputs gracefully
              assertNull(notifications);
          } catch (Exception e) {
          }
      }
  
      @Test
      public void testGetNotificationMessages_HiveEntities_EmptyOutputs() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(false);
          when(context.getOutputs()).thenReturn(new HashSet<>());
          
          dropDatabase = new DropDatabase(context);
  
          // Execute
          List<HookNotification> notifications = dropDatabase.getNotificationMessages();
  
          // Verify
          assertNull(notifications);
      }
  
      @Test
      public void testGetNotificationMessages_HiveEntities_UnsupportedEntityType() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(false);
          
          WriteEntity otherEntity = mock(WriteEntity.class);
          when(otherEntity.getType()).thenReturn(Entity.Type.PARTITION); // Unsupported type
          
          Set<WriteEntity> outputs = new HashSet<>(Arrays.asList(otherEntity));
          when(context.getOutputs()).thenReturn(outputs);
          
          dropDatabase = new DropDatabase(context);
  
          // Execute
          List<HookNotification> notifications = dropDatabase.getNotificationMessages();
  
          // Verify
          assertNull(notifications); // No supported entities, so no notifications
      }
  
      @Test
      public void testGetNotificationMessages_HiveEntities_MixedEntityTypes() {
          // Setup - Test with unsupported entity type only to verify that path
          when(context.isMetastoreHook()).thenReturn(false);
          
          // Unsupported entity only
          WriteEntity partitionEntity = mock(WriteEntity.class);
          when(partitionEntity.getType()).thenReturn(Entity.Type.PARTITION);
          
          Set<WriteEntity> outputs = new HashSet<>(Arrays.asList(partitionEntity));
          when(context.getOutputs()).thenReturn(outputs);
          
          dropDatabase = new DropDatabase(context);
  
          // Execute
          List<HookNotification> notifications = dropDatabase.getNotificationMessages();
  
          // Verify - should return null because no supported entities
          assertNull(notifications);
      }
  
      @Test
      public void testGetNotificationMessages_NullOutputs() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(false);
          when(context.getOutputs()).thenReturn(null);
          
          dropDatabase = new DropDatabase(context);
  
          try {
              // Execute
              List<HookNotification> notifications = dropDatabase.getNotificationMessages();
              
              // Should handle null gracefully - either return null or empty list
              if (notifications != null) {
                  assertTrue(notifications.isEmpty());
              }
          } catch (NullPointerException ignored) {
          }
      }
  
      @Test
      public void testGetNotificationMessages_MetastoreHook_MultipleUsers() {
          // Setup
          when(context.isMetastoreHook()).thenReturn(true);
          
          DropDatabaseEvent dbEvent = mock(DropDatabaseEvent.class);
          Database db = mock(Database.class);
          
          when(dbEvent.getDatabase()).thenReturn(db);
          when(db.getName()).thenReturn("multiUserDb");
          when(context.getMetastoreEvent()).thenReturn(dbEvent);
          when(context.getMetadataNamespace()).thenReturn("test_cluster");
          
          dropDatabase = new DropDatabase(context);
  
          // Execute multiple times to test consistency
          List<HookNotification> notifications1 = dropDatabase.getNotificationMessages();
          List<HookNotification> notifications2 = dropDatabase.getNotificationMessages();
  
          // Verify
          assertNotNull(notifications1);
          assertNotNull(notifications2);
          assertEquals(1, notifications1.size());
          assertEquals(1, notifications2.size());
      }
  
  }
  