public void TestStatusChangeAccept()
        {
            var medicalCode      = "ABC123";
            var infectedStatusId = 1;
            var repository       = ServiceProvider.GetService <IStatusChangeRepository>();
            var changeRequest    = new StatusChangeRequest(infectedStatusId, new DateTime(2020, 4, 1), "Comment");

            Assert.That(repository.TryCreateChangeRequest(medicalCode, changeRequest, "medicalUserToken"),
                        Is.True, "Creating a new code is successful");

            Assert.That(repository.TryAcceptChangeRequest(medicalCode + "invalid", 24),
                        Is.EqualTo(AcceptChangeResponse.Error(AcceptChangeResult.MissingCode)), "Accepting with missing code fails");

            Assert.That(repository.TryAcceptChangeRequest(medicalCode, 0),
                        Is.EqualTo(AcceptChangeResponse.Error(AcceptChangeResult.ExpiredCode)), "Accepting after expiration fails");

            Assert.That(repository.TryAcceptChangeRequest(medicalCode, 24),
                        Is.EqualTo(AcceptChangeResponse.Success(infectedStatusId, changeRequest.StatusChangedOn)),
                        "Accepting with good code succeeds");

            // verify that AcceptedAt is set
            var statusChange = new Table <StatusChange>(CassandraSession.Session)
                               .FirstOrDefault(row => row.MedicalCode == medicalCode)
                               .Execute();

            Assert.That(statusChange.AcceptedAt, Is.Not.Null);

            Assert.That(
                repository.TryAcceptChangeRequest(medicalCode, 24),
                Is.EqualTo(AcceptChangeResponse.Error(AcceptChangeResult.ReusedCode)), "Accepting with a taken code fails");
        }
        public AcceptChangeResponse TryAcceptChangeRequest(string medicalCode, int expirationHours)
        {
            var statusChange = new Table <StatusChange>(session)
                               .FirstOrDefault(row => row.MedicalCode == medicalCode)
                               .Execute();

            if (statusChange == null)
            {
                return(AcceptChangeResponse.Error(AcceptChangeResult.MissingCode));
            }
            if (statusChange.AcceptedAt != null)
            {
                return(AcceptChangeResponse.Error(AcceptChangeResult.ReusedCode));
            }

            if (statusChange.CreatedAt.AddHours(expirationHours) < DateTime.UtcNow)
            {
                return(AcceptChangeResponse.Error(AcceptChangeResult.ExpiredCode));
            }

            // CosmosDB doesn't support this Lightweight Transaction
            //return new Table<StatusChangeAccepted>(session)
            //    .Where(row => row.MedicalCode == medicalCode)
            //    .Select(row => new StatusChangeAccepted { AcceptedAt = DateTime.UtcNow })
            //    .UpdateIf(row => row.AcceptedAt == null)
            //    .Execute()
            //    .Applied;

            new Table <StatusChangeAccepted>(session)
            .Where(row => row.MedicalCode == medicalCode)
            .Select(row => new StatusChangeAccepted {
                AcceptedAt = DateTime.UtcNow
            })
            .Update()
            .Execute();

            return(AcceptChangeResponse.Success(statusChange.StatusId, statusChange.StatusChangedOn));
        }