Jasmine: Mocking API requests in an Angular service spec

Situation: You want to write a spec for a function inside an Angular service. This function at some point makes an API request and acts upon response. Notably, your Angular app employs uiRouter, although it is not used nor actually required for this test.

Working test setup

# Capitalized expressions are intended to be replaced with YOUR values

describe 'SERVICE', ->

  beforeEach ->
    module 'MODULE'

    module ($urlRouterProvider) ->
      # Prevent uiRouter's initialization, i.e. do not sync the current URL
      # with its r...

Limitations you should be aware of when Internet Explorer 9 parses CSS files

Internet Explorer until version 9 has some limitations when parsing CSS files

Summarized, these are:

  • Up to 31 CSS files or <style> tags per page.
  • Up to 4095 selectors per CSS file.
  • Up to 3 nested @import rules

To test the selector limit for a specific browser, check this CSS selector limitation test website.

When you run into this issue, the following links might be helpful to fix the problem. The Idea is to split up the css ...

HTTPie nice command line HTTP client

HTTPie consists of a single http command designed for painless debugging and interaction with HTTP servers, RESTful APIs, and web services

It easy to use and has very nice defaults and coloured output which makes it good for local testing.

Usage examples with curl equivalent:

# curl post
curl --data "foo=23&bar=42" https://example.org/blub
# httpie post
http https://example.org/blub foo=23 bar=42

# curl localhost
curl localhost:3000/users
# httpie localhost
http :3000/users

xlsxtream: Streaming & Fast XLSX Spreadsheet Writer for Ruby

When writing XLSX files, there are gems like rubyXL or axlsx. While they do offer features like formatting or graphs, to represent spreadsheet cells, they have to keep several Ruby objects in memory. When writing huge files, both will become slow and consume lots of memory.

Enter Xlsxtream, a Ruby XLSX library with less features (e.g. no individual cell styles) but which does away with the memory issue by streaming ...

PostgreSQL's OVERLAPS operator is not fully inclusive

PostgreSQL supports the SQL OVERLAPS operator. You can use it to test if two date ranges overlap:

=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
          ('2001-12-20'::date, '2002-10-30'::date);

overlaps
--------
true

An important caveat is that the date ranges are defined as start <= time < end. As such the later date is not included in the range:

=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
          ('2001-12-21'::date, '2002-10-30'::date);

overlaps
--------
false

Also compar...

chromedriver-helper gem in Gemfile might break you selenium tests (of other projects)

Summary: Don't add chromedriver-helper to the Gemfile

  • the executables might break your tests in projects where chromedriver-helper is not in the Gemfile
  • developers with different chrome versions will have problems using the same chromedriver-helper version

Background

If you install the chromedriver-helper gem, but don't have it in you Gemfile, your selenium tests might fail with:

Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver 127.0.0.1:9515

The reason is that chromedriver-helper ov...

Inspecting Angular 1.x UI Router

If your Angular app has some decent complexity, it will not be easy to use UI Router straight away. Here are some hints on how to get around.

Accessing the UI Router $state service from the browser console

$state = angular.element(document.body).injector().get('$state'): Retrieves the Angular injector and asks it for the $state service.

Inspecting the current state

$state.current

Inspecting params of the current state

$state.params

Heads up: Angular may break links to the current URL (e.g. when using ngInclude)

Angular's location provider stalls links to the current URL, i.e. window.location. As soon as the $location service is activated in an Angular app, it will intercept links. The click event handler is registered in $LocationProvider.$get().

The motivation is reasonable, as they want to keep the Browser history clean when Angular is controlling it. However, when Angular is NOT controlling your interaction with the browser history (i.e. you're just using Angular as JS sugar on your page), Angular will create the above issue as soon as you u...

Git: creating and deleting a tag

Git has two kind of tags:

  • annotated
  • lightweight

Annotated tags are stored as full objects in the Git database. They’re checksummed; contain the tagger name, email, and date; have a tagging message; and can be signed and verified with GNU Privacy Guard (GPG)

The following command will create a (lightweight) tag:

git tag v0.1

An annotated tag is created by:

git tag -a v0.1 -m "a special tag message"

A normal git push will not push the tag. So in order to publish your (local) tags, you have to

git push --tags
`...

Turning off VCR when stubbing with Webmock

Sometimes when working with VCR you still want to use webmock. Since VCR hooks into webmock and fails when an unknown request is happening, you have to turn it off in order to use webmock like you are used to. Here is how to do this in rspec.

RSpec.configure do |config|
  config.around do | example |
    if example.metadata[:turn_off_vcr]
      VCR.turn_off!
      example.run
      VCR.turn_on!
    else
      example.run
    end
  end
end

Rails + Sidekiq::Web: Configuration for wildcard session cookies

When you're using Sidekiq::Web to monitor the Sidekiq status AND have your session cookie configured to a wildcard domain like .example.com, you need to take an additional step to keep your cookies valid.

Issue

Sidekiq::Web is mounted into your Rails application and will use the Rails session cookie for protection from CSRF attacs. While it somehow figures out the cookie name, it does NOT respect cookie configuration like a custo...

Webservice to test and inspect requests

Requestb.in is a webservice that gives you a temporary URL you can use to test request. The page will automatically record and display the latest web request made to it.

Fix for: "can't convert nil to String" when running "gem update --system"

When attempting to update RubyGems, depending on updates your previously performed, you might run into an error

ERROR:  While executing gem ... (TypeError)
can't convert nil into String

Fix this by running

gem uninstall rubygems-update -a -x

How to install packages from newer Ubuntu releases

We're usually running Ubuntu LTS versions. Sometimes newer hardware requires packages from more recent Ubuntu releases that only come with 6 months of support. If there is really no other way, it's possible to install packages from later Ubuntu releases

Caution: Pay really close attention to what you're doing. Depending on the package, this process may require upgrading a lot of dependencies, possibly breaking the system! You really should not do this unless you've carefully calculated the impact on your system

Preparation

First,...

Selenium: How to close another tab (popup)

If you open a pop-up window [1] in your Selenium tests and you want to close it, you can do this:

# Find our target window
handle = page.driver.find_window("My window title")

# Close it
page.driver.browser.switch_to.window(handle)
page.driver.browser.close

# Have the Selenium driver point to another window
last_handle = page.driver.browser.window_handles.last
page.driver.browser.switch_to.window(last_handle)

Mind these:

  • find_window returns a window handle, which is something like `"{485fa8bd-fa99-...

Ruby: How to make an object that works with multiple assignment

Ruby allows multiple assignment:

a, b, c = o

In order to prove multiple values from a single object, Ruby calls #to_a on the object:

o = String.new('O')
def o.to_a
  [1,2,3]
end

a, b, c = o # Implicit call to #to_a here
a # => 1
b # => 2
c # => 3

Hence, if you want your class to support multiple assignment, make sure to define a #to_a method.

Fix Slack call overlay on Awesome WM

If you use awesome and make a Slack call, you'll constantly have an overlay window pop up taking over half of your screen.

To fix this, add the following rule to your awful.rules.rules section in your rc.lua:

awful.rules.rules = {
  -- ...
  { rule = { name = "Slack Call Minipanel" }, properties = { floating = true, ontop = true } },
}

Spreewald: Content-Disposition not set when testing a download's filename

Precondition

  • You are not using javascript tests
  • The file is served from a public folder (not via controller)

Problem description

If you deliver files from a public folder it might be that the Content-Disposition header is not set. That's why the following spreewald step might raise an error:

Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
     got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)

Solution

One solution...

Capybara steps to match stuff within any selector

These steps are now part of Spreewald.

Since Capybara 0.4.1 a within scope will only look at the first element that matches. We find this behavior to be impractical, but it is by design.

In order to perform a test or action in all matching elements, do not use within but prefer the attached "inside any" Cucumber steps like these:

When I follow "Foo" inside any "table"
Then I should see "Bar" inside any "li"

How to fix broken font collisions in wkhtmltopdf

If you are using PDFKit / wkhtmltopdf, you might as well want to use custom fonts in your stylesheets. Usually this should not be a problem, but at times they include misleading Meta-information that leads to a strange error in the PDF.

The setup

  • The designer gave you two fonts named something like BrandonText-Regular and BrandonText-Bold. (With flawed Meta-information)
  • You have a HTML string to be rendered by PDFKit
  • For demonstration purposes, this strin...

How to add a custom dictionary to Ruby Mine

  1. Download the dictionary from http://www.winedt.org/dict.html, e.g. http://www.winedt.org/dict/de_neu.zip
  2. unzip de_neu.zip
  3. mkdir ~/Documents/dic
  4. iconv -f UTF-16 -t UTF-8 de_neu.dic -o ~/Documents/dic/de_neu_utf8.dic
  5. In RubyMine: Go to Settings (CTRL + ALT + S) > Editor > Spelling > Dictionaries and add the folder ~/Documents/dic

How to move all files in a folder to a new subfolder

Let's say you have a folder images and want to to move all files in there to a new subfolder public.

cd images
mkdir public
mv !(public) public

The !(public) excludes the new subfolder itself from being moved.

How to exploit websites that include user input in their CSS

The linked article shows how to exploit websites that include unsanitized user input in their CSS.

Although the article often mentions React and CSS-in-JS libraries, the methods are applicable to any web app that injects user input into style tags or properties.

Also, sanitizing user input for CSS injection is much harder than sanitizing HTML.

A Theme Switcher

Hack to implement an inverted "night mode" theme with a few lines of CSS.

Colors in images are preserved.