Using == in this case resolves to System.Reference.Equals. 
.Equals is a virtual method so the overridden version will be used, in this case it will be content comparison for string.
The first test compares a local variable to a literal (interned) string.
The second test compares the same interned string so both == and Equals return true.
If you change your TestMethod1() to this:  
        Assert.IsTrue(Foo<string>.Foo1(name, name));
it will pass because you are comparing the same object, so the reference equality returns true.
Edit: If we add this method:
    public static bool Foo3(string item1, string item2)
    {
        return item1 == item2;
    }
Then the following test will return true:
    Assert.IsTrue(Foo<string>.Foo3(name, "str1"));
because C# will resolve == in this case to the string value check.
This question is really a duplicate of this, with additional generic complexity.
Edit 2:
OK, time to dive into the MSIL. Foo1 looks like this:
.method public hidebysig static bool  Foo1(!T item1,
                                           !T item2) cil managed
{
  // Code size       20 (0x14)
  .maxstack  2
  .locals init ([0] bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  box        !T
  IL_0007:  ldarg.1
  IL_0008:  box        !T
  IL_000d:  ceq
  IL_000f:  stloc.0
  IL_0010:  br.s       IL_0012
  IL_0012:  ldloc.0
  IL_0013:  ret
} // end of method Foo`1::Foo1
You can see here it is using ceq which is Push 1 (of type int32) if value1 equals value2, else push 0.
Here is Foo2:
.method public hidebysig static bool  Foo2(!T item1,
                                           !T item2) cil managed
{
  // Code size       23 (0x17)
  .maxstack  2
  .locals init ([0] bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  box        !T
  IL_0007:  ldarg.1
  IL_0008:  box        !T
  IL_000d:  callvirt   instance bool [mscorlib]System.Object::Equals(object)
  IL_0012:  stloc.0
  IL_0013:  br.s       IL_0015
  IL_0015:  ldloc.0
  IL_0016:  ret
} // end of method Foo`1::Foo2
This uses System.Object::Equals - this is the virtual method and behaves as such, being overridden in the concrete type of the parameter - in this case string.
Foo3 (which I added, which uses == on declared string parameters) looks like this:
.method public hidebysig static bool  Foo3(string item1,
                                           string item2) cil managed
{
  // Code size       13 (0xd)
  .maxstack  2
  .locals init ([0] bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.1
  IL_0003:  call       bool [mscorlib]System.String::op_Equality(string,
                                                                 string)
  IL_0008:  stloc.0
  IL_0009:  br.s       IL_000b
  IL_000b:  ldloc.0
  IL_000c:  ret
} // end of method Foo`1::Foo3
Here we observe explicit use of the System.String::op_Equality(string, string) which is the string value check comparison.