thephpleague / fractal

Output complex, flexible, AJAX/RESTful data structures.
fractal.thephpleague.com
MIT License
3.52k stars 350 forks source link

Unit testing transformers #228

Closed auro1 closed 8 years ago

auro1 commented 9 years ago

Hey :-)

I've been googling and trying to find past issues with this; but can you give me a head start on how I would unit test my transformers? I've been trying to wrap my head around this for hours! :+1:

bencromwell commented 9 years ago

Can you post an example transformer?

It should be as straightforward as instantiating it, passing an instance of your domain model to transform and verifying the contents of the array returned matches what you expected.

If you have an include, then also pass your domain model to it, and verify that the returned League\Fractal\Resource\Item contains what you expected if the relation exists and fails nicely if it doesn't.

auro1 commented 9 years ago

<?php namespace App\Api\v0\Transformers;

use App\Models\Contact;
use League\Fractal\TransformerAbstract;

class ContactTransformer extends TransformerAbstract
{
    protected $availableIncludes = [
        'contact_type',
        'parish',
        'organization',
        'contact_data'
    ];

    protected $defaultIncludes = [
        'organization',
    ];

    public function transform(Contact $contact)
    {
        // Label field
        $label = $contact->name;
        if (!empty($contact->address))
        {
            $label .= ', ' . $contact->address . ', ' . $contact->postcode . ' ' . $contact->city;
        }
        elseif (!empty($contact->phone))
        {
            $label .= ', tlf ' . $contact->phone;
        }

        if (!empty($contact->GetData('sogn')))
        {
            $label .= ', ' . $contact->GetData('sogn');
        }

        // Basic Data
        $dataArray = [
            'id' => $contact->id,
            'label' => $label,
            'read_only' => ((empty($contact->organization_id)) ? 'true' : false),
            'cpr' => $contact->cpr,
            'vat' => $contact->vat,
            'p' => $contact->p,
            'external_id' => $contact->external_id,
            'created_at' => $contact->created_at,
            'updated_at' => $contact->updated_at,
            'deleted_at' => $contact->deleted_at,
            'name' => $contact->name,
            'address_att' => $contact->address_att,
            'address' => $contact->address,
            'address_co' => $contact->address_co,
            'address_2' => $contact->address_2,
            'postcode' => $contact->postcode,
            'city' => $contact->city,
            'country' => $contact->country,
            'phone' => $contact->phone,
            'email' => $contact->email
        ];

        // Extra properties from ContactData
        $contact_datas = $contact->contact_data()->get();
        foreach($contact_datas AS $contact_data)
        {
            $dataArray[$contact_data->key] = $contact_data->value;
        }

        // Return it
        return $dataArray;
    }

    public function includeParish(Contact $contact)
    {
        $parish = $contact->parish()->first();

        if ($parish)
        {
            return $this->item($parish, new ContactTransformer);
        }

        return null;
    }

    public function includeOrganization(Contact $contact)
    {
        $organization = $contact->organization()->first();

        if ($organization) {
            return $this->item($organization, new OrganizationTransformer);
        }

        return null;
    }

    public function includeContactType(Contact $contact)
    {
        $contact_type = $contact->contact_type()->first();

        if ($contact_type)
        {
            return $this->item($contact_type, new ContactTypeTransformer);
        }

        return null;
    }

    public function includeContactData(Contact $contact)
    {
        $contact_data = $contact->contact_data()->get();

        if ($contact_data)
        {
            return $this->collection($contact_data, new ContactDataTransformer);
        }

        return null;
    }
}