config = $this->createMock(Config::class); $this->logger = $this->createMock(Logger::class); } // Scenario: DNS already matches public IP, so no update should occur: public function testNoChangesNeeded() { $api = $this->createMock(PorkbunAPI::class); // ping() must return yourIp or the command returns STATUS_ERROR immediately: $api->method('ping')->willReturn('{"status":"SUCCESS","yourIp":"1.2.3.4"}'); // retrieve() must return JSON with a records array, otherwise json_decode() fails: $api->method('retrieve')->willReturn(json_encode( [ "records" => [ [ "name" => "test.example.com", "type" => "A", "content" => "1.2.3.4", "id" => "123" ] ] ])); $cmd = new UpdateDnsCommand($this->config, $this->logger); $status = $cmd->run(["script.php", "example.com"], $api, "1.2.3.4"); $this->assertSame(UpdateDnsCommand::STATUS_NOTHING_TO_CHANGE, $status); } // Scenario: DNS is outdated, so edit() should be called and STATUS_UPDATED returned: public function testDnsIsUpdated() { $api = $this->createMock(PorkbunAPI::class); // ping() must return yourIp or the command returns STATUS_ERROR immediately: $api->method('ping')->willReturn('{"status":"SUCCESS","yourIp":"1.2.3.4"}'); // retrieve() must return JSON with a records array, otherwise json_decode() fails: $api->method('retrieve')->willReturn(json_encode( [ "records" => [ [ "name" => "test.example.com", "type" => "A", "content" => "5.6.7.8", "id" => "123" ] ] ])); // edit() must return a SUCCESS status or the command returns STATUS_ERROR: $api->method('edit')->willReturn(json_encode(["status" => "SUCCESS"])); // When DNS is updated, the command must record the change in the log exactly once: $this->logger->expects($this->once())->method('log')->with($this->stringContains("Updated DNS")); $cmd = new UpdateDnsCommand($this->config, $this->logger); $status = $cmd->run(["script.php", "example.com"], $api, "1.2.3.4"); $this->assertSame(UpdateDnsCommand::STATUS_UPDATED, $status); } }