/**
  * Ensure that related objects are disassociated on live
  */
 public function testUnlinkDisassociated()
 {
     $this->publishAllFixtures();
     /** @var ChangeSetTest_Base $base */
     $base = $this->objFromFixture(ChangeSetTest_Base::class, 'base');
     /** @var ChangeSetTest_Mid $mid1 $mid2 */
     $mid1 = $this->objFromFixture(ChangeSetTest_Mid::class, 'mid1');
     $mid2 = $this->objFromFixture(ChangeSetTest_Mid::class, 'mid2');
     // Remove mid1 from stage
     $this->assertEquals($base->ID, $mid1->BaseID);
     $this->assertEquals($base->ID, $mid2->BaseID);
     $mid1->deleteFromStage(Versioned::DRAFT);
     // Publishing recursively should unlinkd this object
     $changeset = new ChangeSet();
     $changeset->write();
     $changeset->addObject($base);
     // Assert changeset only contains root object
     $this->assertChangeSetLooksLike($changeset, ['ChangeSetTest_Base.base' => ChangeSetItem::EXPLICITLY]);
     $changeset->publish();
     // mid1 on live exists, but has BaseID set to zero
     $mid1Live = Versioned::get_by_stage(ChangeSetTest_Mid::class, Versioned::LIVE)->byID($mid1->ID);
     $this->assertNotNull($mid1Live);
     $this->assertEquals($mid1->ID, $mid1Live->ID);
     $this->assertEquals(0, $mid1Live->BaseID);
     // mid2 on live exists and retains BaseID
     $mid2Live = Versioned::get_by_stage(ChangeSetTest_Mid::class, Versioned::LIVE)->byID($mid2->ID);
     $this->assertNotNull($mid2Live);
     $this->assertEquals($mid2->ID, $mid2Live->ID);
     $this->assertEquals($base->ID, $mid2Live->BaseID);
 }
 public function testPublish()
 {
     $this->publishAllFixtures();
     $base = $this->objFromFixture('ChangeSetTest_Base', 'base');
     $baseID = $base->ID;
     $baseBefore = $base->Version;
     $end1 = $this->objFromFixture('ChangeSetTest_End', 'end1');
     $end1ID = $end1->ID;
     $end1Before = $end1->Version;
     // Create a new changest
     $changeset = new ChangeSet();
     $changeset->write();
     $changeset->addObject($base);
     $changeset->addObject($end1);
     // Make a lot of changes
     // - ChangeSetTest_Base.base modified
     // - ChangeSetTest_End.end1 deleted
     // - new ChangeSetTest_Mid added
     $base->Foo = 343;
     $base->write();
     $baseAfter = $base->Version;
     $midNew = new ChangeSetTest_Mid();
     $midNew->Bar = 39;
     $midNew->write();
     $midNewID = $midNew->ID;
     $midNewAfter = $midNew->Version;
     $end1->delete();
     $changeset->addObject($midNew);
     // Publish
     $this->logInWithPermission('ADMIN');
     $this->assertTrue($changeset->canPublish());
     $this->assertTrue($changeset->isSynced());
     $changeset->publish();
     $this->assertEquals(ChangeSet::STATE_PUBLISHED, $changeset->State);
     // Check each item has the correct before/after version applied
     $baseChange = $changeset->Changes()->filter(['ObjectClass' => 'ChangeSetTest_Base', 'ObjectID' => $baseID])->first();
     $this->assertEquals((int) $baseBefore, (int) $baseChange->VersionBefore);
     $this->assertEquals((int) $baseAfter, (int) $baseChange->VersionAfter);
     $this->assertEquals((int) $baseChange->VersionBefore + 1, (int) $baseChange->VersionAfter);
     $this->assertEquals((int) $baseChange->VersionAfter, (int) Versioned::get_versionnumber_by_stage('ChangeSetTest_Base', Versioned::LIVE, $baseID));
     $end1Change = $changeset->Changes()->filter(['ObjectClass' => 'ChangeSetTest_End', 'ObjectID' => $end1ID])->first();
     $this->assertEquals((int) $end1Before, (int) $end1Change->VersionBefore);
     $this->assertEquals(0, (int) $end1Change->VersionAfter);
     $this->assertEquals(0, (int) Versioned::get_versionnumber_by_stage('ChangeSetTest_End', Versioned::LIVE, $end1ID));
     $midNewChange = $changeset->Changes()->filter(['ObjectClass' => 'ChangeSetTest_Mid', 'ObjectID' => $midNewID])->first();
     $this->assertEquals(0, (int) $midNewChange->VersionBefore);
     $this->assertEquals((int) $midNewAfter, (int) $midNewChange->VersionAfter);
     $this->assertEquals((int) $midNewAfter, (int) Versioned::get_versionnumber_by_stage('ChangeSetTest_Mid', Versioned::LIVE, $midNewID));
     // Test trying to re-publish is blocked
     $this->setExpectedException('BadMethodCallException', "ChangeSet can't be published if it has been already published or reverted.");
     $changeset->publish();
 }