cms icon indicating copy to clipboard operation
cms copied to clipboard

[4.x]: Trying to create an entry programmatically in Codecept unit test throws `No primary site exists` error

Open aaronbushnell opened this issue 3 years ago • 0 comments

What happened?

Description

When we try to create an entry using new Entry() in our unit test we get the following error:

There was 1 error:
1) PageTest: Entry creation
 Test  tests/Unit/PageTest.php:testEntryCreation
                                                               
  [craft\errors\SiteNotFoundException] No primary site exists  
                                                               
#1  /Users/aaron/Code/project/vendor/craftcms/cms/src/services/Sites.php:513
#2  /Users/aaron/Code/project/vendor/craftcms/cms/src/base/Element.php:2049
#3  /Users/aaron/Code/project/vendor/craftcms/cms/src/elements/Entry.php:731
#4  /Users/aaron/Code/project/vendor/yiisoft/yii2/base/BaseObject.php:109
#5  /Users/aaron/Code/project/vendor/craftcms/cms/src/base/Model.php:78
#6  /Users/aaron/Code/project/vendor/craftcms/cms/src/base/Element.php:1908
#7  /Users/aaron/Code/project/tests/Unit/PageTest.php:32
#8  phar:///usr/local/bin/codecept/autoload.php:12
#9  /usr/local/bin/codecept:5

ERRORS!
Tests: 1, Assertions: 1, Errors: 1.

Here's the unit test in question:

<?php

namespace tests\Unit;

use Codeception\Test\Unit;
use Craft;
use craft\elements\Entry;
use UnitTester;

class PageTest extends Unit
{
    /** @var UnitTester */
    protected $tester;

    public function testEntryCreation()
    {
        $page = new Entry();
        $page->title = 'Hello World';
        $page->sectionId = 1;
        $page->entryId = 1;
        $page->authorId = 1;
        $page->enabled = true;

        Craft::$app->elements->saveElement($page);
    }
}

And here's my codeception.yml file:

actor: Tester
paths:
  tests: tests
  output: tests/_output
  data: tests/_data
  support: tests/_support
  envs: tests/_envs
bootstrap: _bootstrap.php
params:
  - tests/.env
modules:
  config:
    \craft\test\Craft:
      configFile: "tests/_craft/config/test.php"
      entryUrl: "http://craft-starter.test/index.php"
      projectConfig: { folder: 'config/project' }
      migrations: []
      plugins: []
      cleanup: true
      transaction: true
      dbSetup: { clean: true, setupCraft: true }

I could be misunderstanding the project config vs. "fixture" consideration, but we'd like to use what we have in our Project Config and add "fake entries" for our unit tests. It sounded like that's not possible based on the docs:

If you are using Project Config for your tests, regular database-backed fixtures for Project Config data (i.e sections) may cause syncing issues. We recommended that you set up your environment using the Project Config support only.

Steps to reproduce

  1. Setup a testing suite that utilizes Project Config
  2. Try to create a new Entry element in a unit test

Expected behavior

The unit test should create the entry.

Actual behavior

The entry fails because of a No primary site exists error.

Craft CMS version

Craft Pro 4.2.4

PHP version

8.1.10

Operating system and version

macOS Monterey 12.6 (Darwin 21.6.0)

Database type and version

MySQL 5.7.38

Image driver and version

GD 8.1.10

Installed plugins and versions

  • Blitz: 4.2.1
  • Design Tokens: 1.0.3
  • Navigation: 2.0.5
  • Palette: 3.0.0
  • Redactor: 3.0.2
  • Retour: 4.1.3
  • SEOmatic: 4.0.8
  • Sprig: 2.1.0
  • Super Table: 3.0.1
  • Typed link field: 2.1.4

aaronbushnell avatar Sep 21 '22 14:09 aaronbushnell