describe('Kontrolery', function() {
  var $scope, ctrl;
  // W teście należy wskazać moduł.
  beforeEach(module('guthub'));
  beforeEach(function() {
    this.addMatchers({
      toEqualData: function(expected) {
        return angular.equals(this.actual, expected);
      }
    });
  });

  describe('ListCtrl', function() {
    var mockBackend, recipe;
    // _$httpBackend_ to nazwa taka sama jak $httpBackend. Zastosowany zapis służy do odróżnienia
    // zmiennych wstrzykniętych od zmiennych lokalnych.
    beforeEach(inject(function($rootScope, $controller, _$httpBackend_, Recipe) {
      recipe = Recipe;
      mockBackend = _$httpBackend_;
      $scope = $rootScope.$new();
      ctrl = $controller('ListCtrl', {
        $scope: $scope,
        recipes: [1, 2, 3]
      });
    }));

    it('Wynikiem powinna być lista przepisów kulinarnych', function() {
      expect($scope.recipes).toEqual([1, 2, 3]);
    });
  });

  describe('MultiRecipeLoader', function() {
    var mockBackend, recipe, loader;
    // _$httpBackend_ to nazwa taka sama jak $httpBackend. Zastosowany zapis służy do odróżnienia
    // zmiennych wstrzykniętych od zmiennych lokalnych.
    beforeEach(inject(function(_$httpBackend_, Recipe, MultiRecipeLoader) {
      recipe = Recipe;
      mockBackend = _$httpBackend_;
      loader = MultiRecipeLoader;
    }));

    it('Wynikiem powinno być wczytanie listy przepisów kulinarnych', function() {
      mockBackend.expectGET('/recipes').respond([{id: 1}, {id: 2}]);

      var recipes;

      var promise = loader();
      promise.then(function(rec) {
        recipes = rec;
      });

      expect(recipes).toBeUndefined();

      mockBackend.flush();

      expect(recipes).toEqualData([{id: 1}, {id: 2}]);
    });
  });

  describe('EditController', function() {
    var mockBackend, location;
    beforeEach(inject(function($rootScope, $controller, _$httpBackend_, $location, Recipe) {
      mockBackend = _$httpBackend_;
      location = $location;
      $scope = $rootScope.$new();

      ctrl = $controller('EditCtrl', {
        $scope: $scope,
        $location: $location,
        recipe: new Recipe({id: 1, title: 'Przepis'})
      });
    }));

    it('Wynikiem powinien być zapisany przepis kulinarny', function() {
      mockBackend.expectPOST('/recipes/1', {id: 1, title: 'Recipe'}).respond({id: 2});

      // Ustawienie innej wartości, aby mieć gwarancję jej zmiany podczas testu.
      location.path('test');

      $scope.save();
      expect(location.path()).toEqual('/test');

      mockBackend.flush();

      expect(location.path()).toEqual('/view/2');
    });

    it('Wynikiem powinno być usunięcie przepisu kulinarnego', function() {
      expect($scope.recipe).toBeTruthy();
      location.path('test');

      $scope.remove();

      expect($scope.recipe).toBeUndefined();
      expect(location.path()).toEqual('/');
    });
  });
  // Miejsce na pozostałe kontrolery.

});
