/**
 * Copyright 2009-2018 the original author or authors.
 *
 * Licensed 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 net.javacrumbs.shedlock.provider.mongo;

import com.mongodb.MongoClient;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.mongo.tests.MongodForTestsFactory;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.test.support.AbstractLockProviderIntegrationTest;
import org.bson.Document;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Date;

import static com.mongodb.client.model.Filters.eq;
import static net.javacrumbs.shedlock.provider.mongo.MongoLockProvider.*;
import static org.assertj.core.api.Assertions.assertThat;

public class MongoLockProviderIntegrationTest extends AbstractLockProviderIntegrationTest {
    private static MongodForTestsFactory mongoFactory;

    private static final String COLLECTION_NAME = "Shedlock";
    private static final String DB_NAME = "db";
    private MongoClient mongo;

    @Before
    public void createLockProvider() throws UnknownHostException {
        mongo = mongoFactory.newMongo();
        mongo.getDatabase(DB_NAME).drop();
    }

    @Override
    protected LockProvider getLockProvider() {
        return new MongoLockProvider(mongo, DB_NAME, COLLECTION_NAME);
    }

    @Override
    protected void assertUnlocked(String lockName) {
        Document lockDocument = getLockDocument(lockName);
        assertThat((Date) lockDocument.get(LOCK_UNTIL)).isBeforeOrEqualsTo(now());
        assertThat((Date) lockDocument.get(LOCKED_AT)).isBeforeOrEqualsTo(now());
        assertThat((String) lockDocument.get(LOCKED_BY)).isNotEmpty();
    }

    private Date now() {
        return new Date();
    }

    @Override
    protected void assertLocked(String lockName) {
        Document lockDocument = getLockDocument(lockName);
        assertThat((Date) lockDocument.get(LOCK_UNTIL)).isAfter(now());
        assertThat((Date) lockDocument.get(LOCKED_AT)).isBeforeOrEqualsTo(now());
        assertThat((String) lockDocument.get(LOCKED_BY)).isNotEmpty();
    }

    private Document getLockDocument(String lockName) {
        return mongo.getDatabase(DB_NAME).getCollection(COLLECTION_NAME).find(eq(ID, lockName)).first();
    }

    @BeforeClass
    public static void startMongo() throws IOException {
        mongoFactory = new MongodForTestsFactory(Version.Main.V3_2);
    }

    @AfterClass
    public static void stopMongo() {
        mongoFactory.shutdown();
    }
}
@@ -692,24 +692,71 @@
 ongoClient;%0A
+import com.mongodb.client.result.DeleteResult;%0A
 import de.fl
@@ -794,24 +794,24 @@
 on.Version;%0A
-
 import de.fl
@@ -1100,16 +1100,39 @@
 reClass;
+%0Aimport org.junit.Test;
 %0A%0Aimport
@@ -1340,16 +1340,16 @@
 ider.*;%0A
-
 import s
@@ -1397,16 +1397,75 @@
 ertThat;
+%0Aimport static org.assertj.core.api.Assumptions.assumeThat;
 %0A%0Apublic
@@ -3250,10 +3250,530 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void shouldLockWhenDocumentRemovedExternally() %7B%0A        LockProvider provider = getLockProvider();%0A        assertThat(provider.lock(lockConfig(LOCK_NAME1))).isNotEmpty();%0A        assertLocked(LOCK_NAME1);%0A%0A        DeleteResult result = mongo.getDatabase(DB_NAME).getCollection(COLLECTION_NAME).deleteOne(eq(ID, LOCK_NAME1));%0A        assumeThat(result.getDeletedCount()).isEqualTo(1);%0A%0A        assertThat(provider.lock(lockConfig(LOCK_NAME1))).isNotEmpty();%0A        assertLocked(LOCK_NAME1);%0A    %7D
 %0A%7D

Check external lock document removal case in MongoLockProviderIntegrationTest